From 28d34d196e96d7ea62b3d1e03a48e0ac9dcb18ed Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 29 May 2020 13:08:55 +0200 Subject: Debugger: Fix QJson dumper for Qt >= 5.15 Storage is internally based on QCbor now. Since this works better when having dumpers for QCbor values, add those, too, for Numbers, Strings, Arrays, Maps for now. None of the custom types. Fixes: QTCREATORBUG-23827 Change-Id: Idf281d859aaf8556d9895646bbc091af85b34157 Reviewed-by: David Schulz --- share/qtcreator/debugger/dumper.py | 41 +++++--- share/qtcreator/debugger/qttypes.py | 205 +++++++++++++++++++++++++++++++++++- tests/auto/debugger/tst_dumpers.cpp | 196 +++++++++++++++++++++++++++++----- 3 files changed, 400 insertions(+), 42 deletions(-) diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py index 7df90b65db..2b0ad8de5c 100644 --- a/share/qtcreator/debugger/dumper.py +++ b/share/qtcreator/debugger/dumper.py @@ -558,30 +558,32 @@ class DumperBase(): return 0, size return size, limit - def vectorDataHelper(self, addr): + def vectorDataHelper(self, vector_data_ptr): + # vector_data_ptr is what is e.g. stored in a QVector's d_ptr. if self.qtVersion() >= 0x050000: if self.ptrSize() == 4: - (ref, size, alloc, offset) = self.split('IIIp', addr) + (ref, size, alloc, offset) = self.split('IIIp', vector_data_ptr) else: - (ref, size, alloc, pad, offset) = self.split('IIIIp', addr) + (ref, size, alloc, pad, offset) = self.split('IIIIp', vector_data_ptr) alloc = alloc & 0x7ffffff - data = addr + offset + data = vector_data_ptr + offset else: - (ref, alloc, size) = self.split('III', addr) - data = addr + 16 + (ref, alloc, size) = self.split('III', vector_data_ptr) + data = vector_data_ptr + 16 self.check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000) return data, size, alloc - def byteArrayDataHelper(self, addr): + def byteArrayDataHelper(self, bytearray_data_ptr): + # bytearray_data_ptr is what is e.g. stored in a QByteArray's d_ptr. if self.qtVersion() >= 0x050000: # QTypedArray: # - QtPrivate::RefCount ref # - int size # - uint alloc : 31, capacityReserved : 1 # - qptrdiff offset - (ref, size, alloc, offset) = self.split('IIpp', addr) + (ref, size, alloc, offset) = self.split('IIpp', bytearray_data_ptr) alloc = alloc & 0x7ffffff - data = addr + offset + data = bytearray_data_ptr + offset if self.ptrSize() == 4: data = data & 0xffffffff else: @@ -593,19 +595,19 @@ class DumperBase(): # - [padding] # - char *data; if self.ptrSize() == 4: - (ref, alloc, size, data) = self.split('IIIp', addr) + (ref, alloc, size, data) = self.split('IIIp', bytearray_data_ptr) else: - (ref, alloc, size, pad, data) = self.split('IIIIp', addr) + (ref, alloc, size, pad, data) = self.split('IIIIp', bytearray_data_ptr) else: # Data: # - QShared count; # - QChar *unicode # - char *ascii # - uint len: 30 - (dummy, dummy, dummy, size) = self.split('IIIp', addr) - size = self.extractInt(addr + 3 * self.ptrSize()) & 0x3ffffff + (dummy, dummy, dummy, size) = self.split('IIIp', bytearray_data_ptr) + size = self.extractInt(bytearray_data_ptr + 3 * self.ptrSize()) & 0x3ffffff alloc = size # pretend. - data = self.extractPointer(addr + self.ptrSize()) + data = self.extractPointer(bytearray_data_ptr + self.ptrSize()) return data, size, alloc # addr is the begin of a QByteArrayData structure @@ -3844,6 +3846,17 @@ class DumperBase(): return val raise RuntimeError('EXPECTING ADDRESS OR BYTES, GOT %s' % type(datish)) + def createProxyValue(self, proxy_data, type_name): + tdata = self.TypeData(self) + tdata.name = type_name + tdata.typeId = type_name + tdata.code = TypeCode.Struct + self.registerType(type_name, tdata) + val = self.Value(self) + val.type = self.Type(self, type_name) + val.ldata = proxy_data + return val + def createContainerItem(self, data, innerTypish, container): innerType = self.createType(innerTypish) name = self.qtNamespace() + '%s<%s>' % (container, innerType.name) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 8a33e3306e..0d57f6e1a7 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -24,9 +24,10 @@ ############################################################################ import platform +import struct import re -from dumper import Children, SubItem, UnnamedSubItem, toInteger -from utils import DisplayFormat +from dumper import Children, SubItem, UnnamedSubItem, toInteger, DumperBase +from utils import DisplayFormat, TypeCode def qdump__QAtomicInt(d, value): @@ -2969,6 +2970,12 @@ def qdumpHelper_QJsonObject(d, data, obj): def qdump__QJsonValue(d, value): (data, dd, t) = value.split('QpI') + + if d.qtVersion() >= 0x050f00: + value = d.createProxyValue((data, dd, t, False), 'QCborValue_proxy') + d.putItem(value) + return + if t == 0: d.putType('QJsonValue (Null)') d.putValue('Null') @@ -3005,10 +3012,20 @@ def qdump__QJsonValue(d, value): def qdump__QJsonArray(d, value): + if d.qtVersion() >= 0x050f00: + _, container_ptr = value.split('pp') + qdumpHelper_QCbor_array(d, container_ptr, False) + return + qdumpHelper_QJsonArray(d, value['d'].pointer(), value['a'].pointer()) def qdump__QJsonObject(d, value): + if d.qtVersion() >= 0x050f00: + _, container_ptr = value.split('pp') + qdumpHelper_QCbor_map(d, container_ptr, False) + return + qdumpHelper_QJsonObject(d, value['d'].pointer(), value['o'].pointer()) @@ -3077,3 +3094,187 @@ def qdump__qfloat16(d, value): d.putValue(res) d.putNumChild(1) d.putPlainChildren(value) + + + +def qdumpHelper_QCbor_string(d, container_ptr, element_index, is_bytes): + # d.split('i@{QByteArray::size_type}pp', container_ptr) doesn't work with CDB, so be explicit: + offset = 2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8 + data_d_ptr, elements_d_ptr = d.split('pp', container_ptr + offset) + elements_data_ptr, elements_size, _ = d.vectorDataHelper(elements_d_ptr) + element_at_n_addr = elements_data_ptr + element_index * 16 # sizeof(QtCbor::Element) == 15 + element_value, _, element_flags = d.split('qII', element_at_n_addr) + enc = 'latin1' if is_bytes or (element_flags & 8) else 'utf16' + bytedata, _, _ = d.byteArrayDataHelper(data_d_ptr) + bytedata += element_value + if d.qtVersion() >= 0x060000: + bytedata_len = d.extractInt64(bytedata) + bytedata_data = bytedata + 8 + else: + bytedata_len = d.extractInt(bytedata) + bytedata_data = bytedata + 4 # sizeof(QtCbor::ByteData) header part + + elided, shown = d.computeLimit(bytedata_len, d.displayStringLimit) + res = d.readMemory(bytedata_data, shown) + d.putValue(res, enc, elided=elided) + + +def qdumpHelper_QCborArray_valueAt(d, container_ptr, elements_data_ptr, idx, bytedata, is_cbor): + element_at_n_addr = elements_data_ptr + idx * 16 # sizeof(QtCbor::Element) == 15 + element_value, element_type, element_flags = d.split('qII', element_at_n_addr) + element_container, _, _ = d.split('pII', element_at_n_addr) + if element_flags & 1: # QtCbor::Element::IsContainer + return d.createProxyValue((-1, element_container, element_type, is_cbor), 'QCborValue_proxy') + if element_flags & 2: # QtCbor::Element::HasByteData + return d.createProxyValue((idx, container_ptr, element_type, is_cbor), 'QCborValue_proxy') + return d.createProxyValue((element_value, 0, element_type, is_cbor), 'QCborValue_proxy') + + +def qdumpHelper_QCbor_array(d, container_ptr, is_cbor): + if not container_ptr: + d.putItemCount(0) + return + # d.split('i@{QByteArray::size_type}pp', container_ptr) doesn't work with CDB, so be explicit: + offset = 2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8 + data_d_ptr, elements_d_ptr = d.split('pp', container_ptr + offset) + elements_data_ptr, elements_size, _ = d.vectorDataHelper(elements_d_ptr) + d.putItemCount(elements_size) + if d.isExpanded(): + bytedata, _, _ = d.byteArrayDataHelper(data_d_ptr) + with Children(d, maxNumChild=1000): + for i in range(elements_size): + d.putSubItem(i, qdumpHelper_QCborArray_valueAt(d, container_ptr, elements_data_ptr, i, bytedata, is_cbor)) + + +def qdump__QCborArray(d, value): + container_ptr = value.extractPointer() + qdumpHelper_QCbor_array(d, container_ptr, True) + + +def qdumpHelper_QCbor_map(d, container_ptr, is_cbor): + if not container_ptr: + d.putItemCount(0) + return + # d.split('i@{QByteArray::size_type}pp', container_ptr) doesn't work with CDB, so be explicit: + offset = 2 * d.ptrSize() if d.qtVersion() >= 0x060000 else 8 + data_d_ptr, elements_d_ptr = d.split('pp', container_ptr + offset) + elements_data_ptr, elements_size, _ = d.vectorDataHelper(elements_d_ptr) + elements_size = int(elements_size / 2) + d.putItemCount(elements_size) + if d.isExpanded(): + bytedata, _, _ = d.byteArrayDataHelper(data_d_ptr) + with Children(d, maxNumChild=1000): + for i in range(elements_size): + key = qdumpHelper_QCborArray_valueAt(d, container_ptr, elements_data_ptr, 2 * i, bytedata, is_cbor) + val = qdumpHelper_QCborArray_valueAt(d, container_ptr, elements_data_ptr, 2 * i + 1, bytedata, is_cbor) + d.putPairItem(i, (key, val), 'key', 'value') + + +def qdump__QCborMap(d, value): + container_ptr = value.extractPointer() + qdumpHelper_QCbor_map(d, container_ptr, True) + + +def qdump__QCborValue(d, value): + item_data, container_ptr, item_type = value.split('qpi') + d.putItem(d.createProxyValue((item_data, container_ptr, item_type, True), 'QCborValue_proxy')) + +def qdump__QCborValue_proxy(d, value): + item_data, container_ptr, item_type, is_cbor = value.data() + + def typename(key, is_cbor): + if is_cbor: + return { + 'invalid' : 'QCborValue (Invalid)', + 'int' : 'QCborValue (Integer)', + 'false' : 'QCborValue (False)', + 'true' : 'QCborValue (True)', + 'null' : 'QCborValue (Null)', + 'undefined' : 'QCborValue (Undefined)', + 'double' : 'QCborValue (Double)', + 'bytes' : 'QCborValue (ByteArray)', + 'string' : 'QCborValue (String)', + 'map' : 'QCborValue (Map)', + 'array' : 'QCborValue (Array)' + }.get(key, 'QCborValue (Unknown)') + else: + return { + 'invalid' : 'QJsonValue (Invalid)', + 'int' : 'QJsonValue (Number)', + 'false' : 'QJsonValue (Bool)', + 'true' : 'QJsonValue (Bool)', + 'null' : 'QJsonValue (Null)', + 'undefined' : 'QJsonValue (Undefined)', + 'double' : 'QJsonValue (Number)', + 'bytes' : 'QJsonValue (ByteArray)', + 'string' : 'QJsonValue (String)', + 'map' : 'QJsonValue (Object)', + 'array' : 'QJsonValue (Array)' + }.get(key, 'QJsonValue (Unknown)') + + + if item_type == 0xffffffffffffffff: + d.putType(typename('invalid', is_cbor)) + d.putValue('Invalid') + + elif item_type == 0x00: + d.putType(typename('int', is_cbor)) + d.putValue(item_data) + + elif item_type == 0x100 + 20: + d.putType(typename('false', is_cbor)) + d.putValue('False') + + elif item_type == 0x100 + 21: + d.putType(typename('true', is_cbor)) + d.putValue('True') + + elif item_type == 0x100 + 22: + d.putType(typename('null', is_cbor)) + d.putValue('Null') + + elif item_type == 0x100 + 23: + d.putType(typename('undefined', is_cbor)) + d.putValue('Undefined') + + elif item_type == 0x202: + val = struct.unpack('d', struct.pack('q', item_data)) + d.putType(typename('double', is_cbor)) + d.putValue('%f' % val) + + elif item_type == 0x40: + d.putType(typename('bytes', is_cbor)) + qdumpHelper_QCbor_string(d, container_ptr, item_data, True) + + elif item_type == 0x60: + d.putType(typename('string', is_cbor)) + qdumpHelper_QCbor_string(d, container_ptr, item_data, False) + + elif item_type == 0x80: + d.putType(typename('array', is_cbor)) + qdumpHelper_QCbor_array(d, container_ptr, is_cbor) + + elif item_type == 0xa0: + d.putType(typename('map', is_cbor)) + qdumpHelper_QCbor_map(d, container_ptr, is_cbor) + + elif item_type == 0x10000: + d.putType('QCborValue (DateTime)') + d.putValue('DateTime') + + elif item_type == 0x10020: + d.putType('QCborValue (Url)') + d.putValue('Url') + + elif item_type == 0x10023: + d.putType('QCborValue (RegularExpression)') + d.putValue('RegularExpression') + + elif item_type == 0x10025: + d.putType('QCborValue (Uuid)') + d.putValue('Uuid') + + else: + d.putType('QCborValue (Unknown)') + d.putValue(item_data) + diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 9bbd10b266..381a39f339 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -7175,6 +7175,127 @@ void tst_Dumpers::dumper_data() + Check("p", "<5 items>", "@QGraphicsPolygonItem"); + QTest::newRow("QCbor") + << Data("#include \n" + "#if QT_VERSION >= 0x050c00\n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#endif\n", + + "#if QT_VERSION >= 0x050c00\n" + "QCborMap ob0;\n" + "QCborMap ob = QCborMap::fromVariantMap({\n" + " {\"a\", 1},\n" + " {\"bb\", 2},\n" + " {\"ccc\", \"hallo\"},\n" + " {\"s\", \"ssss\"}\n" + "});\n" + "ob.insert(QLatin1String(\"d\"), QCborMap::fromVariantMap({{\"ddd\", 1234}}));\n" + "\n" + "QCborValue a0;\n" + "QCborValue a1(1);\n" + "QCborValue a2(\"asd\");\n" + "QCborValue a3(QString::fromUtf8(\"cöder\"));\n" + "QCborValue a4(1.4);\n" + "QCborValue a5(true);\n" + "QCborValue a6(QByteArray(\"cder\"));\n" + "\n" + "QCborArray aa;\n" + "QCborArray a;\n" + "a.append(a1);\n" + "a.append(a2);\n" + "a.append(a3);\n" + "a.append(a4);\n" + "a.append(a5);\n" + "a.append(a0);\n" + "a.append(ob);\n" + "\n" + "QCborArray b;\n" + "b.append(QCborValue(1));\n" + "b.append(a);\n" + "b.append(QCborValue(2));\n" + "\n" + "QCborArray c;\n" + "for (unsigned int i = 0; i < 32; ++i) {\n" + " c.append(QCborValue(qint64(1u << i) - 1));\n" + " c.append(QCborValue(qint64(1u << i)));\n" + " c.append(QCborValue(qint64(1u << i) + 1));\n" + "}\n" + "for (unsigned int i = 0; i < 32; ++i) {\n" + " c.append(QCborValue(-qint64(1u << i) + 1));\n" + " c.append(QCborValue(-qint64(1u << i)));\n" + " c.append(QCborValue(-qint64(1u << i) - 1));\n" + "}" + "unused(&b, &a, &aa);\n" + "#endif\n", + + "") + + + Cxx11Profile() + + CoreProfile() + + QtVersion(0x50f00) + + MsvcVersion(1900) + + + Check("a0", "Undefined", "QCborValue (Undefined)") + + Check("a1", "1", "QCborValue (Integer)") + + Check("a2", "\"asd\"", "QCborValue (String)") + + Check("a3", "\"cöder\"", "QCborValue (String)") + + Check("a4", "1.400000", "QCborValue (Double)") + + Check("a5", "True", "QCborValue (True)") + + Check("a6", "\"cder\"", "QCborValue (ByteArray)") + + Check("aa", "<0 items>", "@QCborArray") + + Check("a", "<7 items>", "@QCborArray") + + Check("a.0", "[0]", "1", "QCborValue (Integer)") + + Check("a.1", "[1]", "\"asd\"", "QCborValue (String)") + + Check("a.2", "[2]", "\"cöder\"", "QCborValue (String)") + + Check("a.3", "[3]", "1.400000", "QCborValue (Double)") + + Check("a.4", "[4]", "True", "QCborValue (True)") + + Check("a.5", "[5]", "Undefined", "QCborValue (Undefined)") + + Check("a.6", "[6]", "<5 items>", "QCborValue (Map)") + + Check("a.6.0", "[0] \"a\"", "1", "") + + Check("a.6.1", "[1] \"bb\"", "2", "") + + Check("a.6.2", "[2] \"ccc\"", "\"hallo\"", "") + + Check("a.6.3", "[3] \"s\"", "\"ssss\"", "") + + Check("a.6.4", "[4] \"d\"", "<1 items>", "") + + Check("b", "b", "<3 items>" , "@QCborArray") + + Check("b.0", "[0]", "1", "QCborValue (Integer)") + + Check("b.1", "[1]", "<7 items>", "QCborValue (Array)") + + Check("b.1.0", "[0]", "1", "QCborValue (Integer)") + + Check("b.1.1", "[1]", "\"asd\"", "QCborValue (String)") + + Check("b.1.2", "[2]", "\"cöder\"", "QCborValue (String)") + + Check("b.1.3", "[3]", "1.400000", "QCborValue (Double)") + + Check("b.1.4", "[4]", "True", "QCborValue (True)") + + Check("b.1.5", "[5]", "Undefined", "QCborValue (Undefined)") + + Check("b.1.6", "[6]", "<5 items>", "QCborValue (Map)") + + Check("b.2", "[2]", "2", "QCborValue (Integer)") + + Check("c", "c", "<192 items>", "@QCborArray") + + Check("c.0", "[0]", "0", "QCborValue (Integer)") + + Check("c.1", "[1]", "1", "QCborValue (Integer)") + + Check("c.78", "[78]", "67108863", "QCborValue (Integer)") + + Check("c.79", "[79]", "67108864", "QCborValue (Integer)") + + Check("c.94", "[94]", "2147483648", "QCborValue (Integer)") + + Check("c.95", "[95]", "2147483649", "QCborValue (Integer)") + + Check("c.96", "[96]", "0", "QCborValue (Integer)") + + Check("c.97", "[97]", "-1", "QCborValue (Integer)") + + Check("c.174", "[174]", "-67108863", "QCborValue (Integer)") + + Check("c.175", "[175]", "-67108864", "QCborValue (Integer)") + + Check("ob0", "ob0", "<0 items>", "@QCborMap") + + Check("ob", "ob", "<5 items>", "@QCborMap") + + Check("ob.0", "[0] \"a\"", "1", "") + + Check("ob.0.key", "key", "\"a\"", "QCborValue (String)") + + Check("ob.0.value", "value", "1", "QCborValue (Integer)") + + Check("ob.1", "[1] \"bb\"", "2", "") + + Check("ob.2", "[2] \"ccc\"", "\"hallo\"", "") + + Check("ob.3", "[3] \"s\"", "\"ssss\"", "") + + Check("ob.4", "[4] \"d\"", "<1 items>", "") + ; + + + const QtVersion jsonv1{0, 0x50e00}; + const QtVersion jsonv2{0x50e00}; + QTest::newRow("QJson") << Data("#include \n" "#if QT_VERSION >= 0x050000\n" @@ -7185,6 +7306,7 @@ void tst_Dumpers::dumper_data() "#endif\n", "#if QT_VERSION >= 0x050000\n" + "QJsonObject ob0;\n" "QJsonObject ob = QJsonObject::fromVariantMap({\n" " {\"a\", 1},\n" " {\"bb\", 2},\n" @@ -7193,6 +7315,7 @@ void tst_Dumpers::dumper_data() "});\n" "ob.insert(QLatin1String(\"d\"), QJsonObject::fromVariantMap({{\"ddd\", 1234}}));\n" "\n" + "QJsonArray aa;\n" "QJsonArray a;\n" "a.append(QJsonValue(1));\n" "a.append(QJsonValue(\"asd\"));\n" @@ -7217,7 +7340,7 @@ void tst_Dumpers::dumper_data() " c.append(QJsonValue(-qint64(1u << i)));\n" " c.append(QJsonValue(-qint64(1u << i) - 1));\n" "}" - "unused(&ob,&b,&a);\n" + "unused(&ob, &b, &a, &aa);\n" "#endif\n", "") @@ -7227,45 +7350,66 @@ void tst_Dumpers::dumper_data() + QtVersion(0x50000) + MsvcVersion(1900) + + Check("aa", "<0 items>", "@QJsonArray") + Check("a", "<6 items>", "@QJsonArray") + Check("a.0", "[0]", "1", "QJsonValue (Number)") + Check("a.1", "[1]", "\"asd\"", "QJsonValue (String)") + Check("a.2", "[2]", "\"cdfer\"", "QJsonValue (String)") - + Check("a.3", "[3]", "1.4", "QJsonValue (Number)") - + Check("a.4", "[4]", "true", "QJsonValue (Bool)") + + Check("a.3", "[3]", "1.4", "QJsonValue (Number)") % jsonv1 + + Check("a.3", "[3]", "1.400000", "QJsonValue (Number)") % jsonv2 + + Check("a.4", "[4]", "true", "QJsonValue (Bool)") % jsonv1 + + Check("a.4", "[4]", "True", "QJsonValue (Bool)") % jsonv2 + Check("a.5", "[5]", "<5 items>", "QJsonValue (Object)") - + Check("a.5.0", "\"a\"", "1", "QJsonValue (Number)") - + Check("a.5.1", "\"bb\"", "2", "QJsonValue (Number)") - + Check("a.5.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)") - + Check("a.5.3", "\"d\"", "<1 items>", "QJsonValue (Object)") - + Check("a.5.4", "\"s\"", "\"ssss\"", "QJsonValue (String)") + + Check("a.5.0", "\"a\"", "1", "QJsonValue (Number)") % jsonv1 + + Check("a.5.0", "[0] \"a\"", "1", "" ) % jsonv2 + + Check("a.5.1", "\"bb\"", "2", "QJsonValue (Number)") % jsonv1 + + Check("a.5.1", "[1] \"bb\"", "2", "" ) % jsonv2 + + Check("a.5.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)") % jsonv1 + + Check("a.5.2", "[2] \"ccc\"","\"hallo\"", "" ) % jsonv2 + + Check("a.5.3", "\"d\"", "<1 items>", "QJsonValue (Object)") % jsonv1 + + Check("a.5.3", "[3] \"d\"", "<1 items>", "" ) % jsonv2 + + Check("a.5.4", "\"s\"", "\"ssss\"", "QJsonValue (String)") % jsonv1 + + Check("a.5.4", "[4] \"s\"", "\"ssss\"", "" ) % jsonv2 + Check("b", "b", "<3 items>" , "@QJsonArray") + Check("b.0", "[0]", "1", "QJsonValue (Number)") + Check("b.1", "[1]", "<6 items>", "QJsonValue (Array)") - + Check("b.1.0", "[0]", "1", "QJsonValue (Number)") - + Check("b.1.1", "[1]", "\"asd\"", "QJsonValue (String)") - + Check("b.1.2", "[2]", "\"cdfer\"", "QJsonValue (String)") - + Check("b.1.3", "[3]", "1.4", "QJsonValue (Number)") - + Check("b.1.4", "[4]", "true", "QJsonValue (Bool)") - + Check("b.1.5", "[5]", "<5 items>", "QJsonValue (Object)") - + Check("b.2", "[2]", "2", "QJsonValue (Number)") + + Check("b.1.0", "[0]", "1", "QJsonValue (Number)") % jsonv2 + + Check("b.1.1", "[1]", "\"asd\"", "QJsonValue (String)") % jsonv2 + + Check("b.1.2", "[2]", "\"cdfer\"", "QJsonValue (String)") % jsonv2 + + Check("b.1.3", "[3]", "1.4", "QJsonValue (Number)") % jsonv1 + + Check("b.1.3", "[3]", "1.400000", "QJsonValue (Number)") % jsonv2 + + Check("b.1.4", "[4]", "true", "QJsonValue (Bool)") % jsonv1 + + Check("b.1.5", "[5]", "<5 items>", "QJsonValue (Object)") % jsonv2 + + Check("b.2", "[2]", "2", "QJsonValue (Number)") % jsonv2 + Check("c", "c", "<192 items>", "@QJsonArray") - + Check("c.0", "[0]", "0.0", "QJsonValue (Number)") + + Check("c.0", "[0]", "0.0", "QJsonValue (Number)") % jsonv1 + + Check("c.0", "[0]", "0", "QJsonValue (Number)") % jsonv2 + Check("c.1", "[1]", "1", "QJsonValue (Number)") + Check("c.78", "[78]", "67108863", "QJsonValue (Number)") - + Check("c.79", "[79]", "67108864.0", "QJsonValue (Number)") - + Check("c.94", "[94]", "2147483648.0", "QJsonValue (Number)") - + Check("c.95", "[95]", "2147483649.0", "QJsonValue (Number)") - + Check("c.96", "[96]", "0.0", "QJsonValue (Number)") + + Check("c.79", "[79]", "67108864.0", "QJsonValue (Number)") % jsonv1 + + Check("c.79", "[79]", "67108864", " QJsonValue (Number)") % jsonv2 + + Check("c.94", "[94]", "2147483648.0", "QJsonValue (Number)") % jsonv1 + + Check("c.94", "[94]", "2147483648", "QJsonValue (Number)") % jsonv2 + + Check("c.95", "[95]", "2147483649.0", "QJsonValue (Number)") % jsonv1 + + Check("c.95", "[95]", "2147483649", "QJsonValue (Number)") % jsonv2 + + Check("c.96", "[96]", "0.0", "QJsonValue (Number)") % jsonv1 + + Check("c.96", "[96]", "0", "QJsonValue (Number)") % jsonv2 + Check("c.97", "[97]", "-1", "QJsonValue (Number)") + Check("c.174", "[174]", "-67108863", "QJsonValue (Number)") - + Check("c.175", "[175]", "-67108864.0", "QJsonValue (Number)") + + Check("c.175", "[175]", "-67108864.0", "QJsonValue (Number)") % jsonv1 + + Check("c.175", "[175]", "-67108864", "QJsonValue (Number)") % jsonv2 + + Check("ob0", "ob0", "<0 items>", "@QJsonObject") + Check("ob", "ob", "<5 items>", "@QJsonObject") - + Check("ob.0", "\"a\"", "1", "QJsonValue (Number)") - + Check("ob.1", "\"bb\"", "2", "QJsonValue (Number)") - + Check("ob.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)") - + Check("ob.3", "\"d\"", "<1 items>", "QJsonValue (Object)") - + Check("ob.4", "\"s\"", "\"ssss\"", "QJsonValue (String)"); + + Check("ob.0", "\"a\"", "1", "QJsonValue (Number)") % jsonv1 + + Check("ob.0", "[0] \"a\"", "1", "" ) % jsonv2 + + Check("ob.1", "\"bb\"", "2", "QJsonValue (Number)") % jsonv1 + + Check("ob.1", "[1] \"bb\"", "2", "" ) % jsonv2 + + Check("ob.2", "\"ccc\"", "\"hallo\"", "QJsonValue (String)") % jsonv1 + + Check("ob.2", "[2] \"ccc\"", "\"hallo\"", "" ) % jsonv2 + + Check("ob.3", "\"d\"", "<1 items>", "QJsonValue (Object)") % jsonv1 + + Check("ob.3", "[3] \"d\"", "<1 items>", "" ) % jsonv2 + + Check("ob.4", "\"s\"", "\"ssss\"", "QJsonValue (String)") % jsonv1 + + Check("ob.4", "[4] \"s\"", "\"ssss\"", "" ) % jsonv2; QTest::newRow("Q&qstring_literal_temp,V4") -- cgit v1.2.3