qttypes.py 80.8 KB
Newer Older
hjk's avatar
hjk committed
1
2
3
4
5
6
7
8
9

#Note: Keep name-type-value-numchild-extra order

#######################################################################
#
# Dumper Implementations
#
#######################################################################

10
11
from __future__ import with_statement

hjk's avatar
hjk committed
12
13
def qdump__QAtomicInt(d, value):
    d.putValue(value["_q_value"])
hjk's avatar
hjk committed
14
15
16
    d.putNumChild(0)


hjk's avatar
hjk committed
17
18
def qdump__QBasicAtomicInt(d, value):
    d.putValue(value["_q_value"])
19
20
21
    d.putNumChild(0)


hjk's avatar
hjk committed
22
23
24
def qdump__QBasicAtomicPointer(d, value):
    d.putType(value.type)
    p = cleanAddress(value["_q_value"])
25
    d.putValue(p)
hjk's avatar
hjk committed
26
    d.putPointerValue(value.address)
27
    d.putNumChild(p)
hjk's avatar
hjk committed
28
    if d.isExpanded():
29
        with Children(d):
hjk's avatar
hjk committed
30
           d.putItem(value["_q_value"])
31
32


hjk's avatar
hjk committed
33
34
35
def qdump__QByteArray(d, value):
    d.putByteArrayValue(value)
    data, size, alloc = qByteArrayData(value)
36
    d.putNumChild(size)
hjk's avatar
hjk committed
37

hjk's avatar
hjk committed
38
    if d.isExpanded():
39
        innerType = lookupType("char")
hjk's avatar
hjk committed
40
41
        with Children(d, numChild=size, maxNumChild=1000, childType=innerType,
                addrBase=cleanAddress(data), addrStep=1):
42
43
            p = gdb.Value(data.cast(innerType.pointer()))
            for i in d.childRange():
hjk's avatar
hjk committed
44
                d.put('{value="%d"},' % p.dereference())
45
                p += 1
hjk's avatar
hjk committed
46
47


hjk's avatar
hjk committed
48
49
def qdump__QChar(d, value):
    ucs = int(value["ucs"])
50
    d.putValue("'%c' (%d)" % (printableChar(ucs), ucs))
hjk's avatar
hjk committed
51
52
53
    d.putNumChild(0)


54
55
def qform__QModelIndex():
    return "Normal,Enhanced"
56

hjk's avatar
hjk committed
57
def qdump__QAbstractItemModel(d, value):
58
59
60
61
62
    format = d.currentItemFormat()
    if format == 1:
        d.putPlainChildren(value)
        return
    #format == 2:
63
    # Create a default-constructed QModelIndex on the stack.
64
    try:
65
        ri = makeValue(d.ns + "QModelIndex", "-1, -1, 0, 0")
hjk's avatar
hjk committed
66
        this_ = makeExpression(value)
67
        ri_ = makeExpression(ri)
68
69
70
        rowCount = int(parseAndEvaluate("%s.rowCount(%s)" % (this_, ri_)))
        columnCount = int(parseAndEvaluate("%s.columnCount(%s)" % (this_, ri_)))
    except:
hjk's avatar
hjk committed
71
        d.putPlainChildren(value)
72
        return
73
74
    d.putValue("%d x %d" % (rowCount, columnCount))
    d.putNumChild(rowCount * columnCount)
hjk's avatar
hjk committed
75
76
    if d.isExpanded():
        with Children(d, numChild=rowCount * columnCount, childType=ri.type):
77
78
79
            i = 0
            for row in xrange(rowCount):
                for column in xrange(columnCount):
hjk's avatar
hjk committed
80
                    with SubItem(d, i):
81
82
83
84
85
86
                        d.putName("[%s, %s]" % (row, column))
                        mi = parseAndEvaluate("%s.index(%d,%d,%s)"
                            % (this_, row, column, ri_))
                        #warn("MI: %s " % mi)
                        #name = "[%d,%d]" % (row, column)
                        #d.putValue("%s" % mi)
hjk's avatar
hjk committed
87
                        d.putItem(mi)
88
89
90
91
92
93
94
95
                        i = i + 1
                        #warn("MI: %s " % mi)
                        #d.putName("[%d,%d]" % (row, column))
                        #d.putValue("%s" % mi)
                        #d.putNumChild(0)
                        #d.putType(mi.type)
    #gdb.execute("call free($ri)")

96
97
98
def qform__QModelIndex():
    return "Normal,Enhanced"

hjk's avatar
hjk committed
99
def qdump__QModelIndex(d, value):
100
101
102
103
    format = d.currentItemFormat()
    if format == 1:
        d.putPlainChildren(value)
        return
hjk's avatar
hjk committed
104
105
106
107
    r = value["r"]
    c = value["c"]
    p = value["p"]
    m = value["m"]
108
109
    mm = m.dereference()
    mm = mm.cast(mm.type.unqualified())
110
    try:
111
112
113
        mi = makeValue(d.ns + "QModelIndex", "%s,%s,%s,%s" % (r, c, p, m))
        mm_ = makeExpression(mm)
        mi_ = makeExpression(mi)
114
115
116
        rowCount = int(parseAndEvaluate("%s.rowCount(%s)" % (mm_, mi_)))
        columnCount = int(parseAndEvaluate("%s.columnCount(%s)" % (mm_, mi_)))
    except:
hjk's avatar
hjk committed
117
        d.putPlainChildren(value)
118
        return
119
120
121

    try:
        # Access DisplayRole as value
hjk's avatar
hjk committed
122
123
        val = parseAndEvaluate("%s.data(%s, 0)" % (mm_, mi_))
        v = val["d"]["data"]["ptr"]
124
125
126
127
128
129
        d.putStringValue(makeValue(d.ns + 'QString', v))
    except:
        d.putValue("(invalid)")

    if r >= 0 and c >= 0 and not isNull(m):
        d.putNumChild(rowCount * columnCount)
hjk's avatar
hjk committed
130
        if d.isExpanded():
131
132
133
134
            with Children(d):
                i = 0
                for row in xrange(rowCount):
                    for column in xrange(columnCount):
hjk's avatar
hjk committed
135
                        with UnnamedSubItem(d, i):
136
137
138
                            d.putName("[%s, %s]" % (row, column))
                            mi2 = parseAndEvaluate("%s.index(%d,%d,%s)"
                                % (mm_, row, column, mi_))
hjk's avatar
hjk committed
139
                            d.putItem(mi2)
140
                            i = i + 1
hjk's avatar
hjk committed
141
142
                #d.putCallItem("parent", val, "parent")
                #with SubItem(d, "model"):
143
144
145
146
147
148
                #    d.putValue(m)
                #    d.putType(d.ns + "QAbstractItemModel*")
                #    d.putNumChild(1)
    else:
        d.putValue("(invalid)")
        d.putNumChild(0)
hjk's avatar
hjk committed
149
        if d.isExpanded():
150
151
152
153
            with Children(d):
                pass
    #gdb.execute("call free($mi)")

hjk's avatar
hjk committed
154

hjk's avatar
hjk committed
155
def qdump__QDate(d, value):
156
    d.putValue(value["jd"], JulianDate)
157
    d.putNumChild(1)
hjk's avatar
hjk committed
158
    if d.isExpanded():
159
        qt = d.ns + "Qt::"
160
        # FIXME: This improperly uses complex return values.
hjk's avatar
hjk committed
161
162
163
164
        with Children(d):
            d.putCallItem("toString", value, "toString", qt + "TextDate")
            d.putCallItem("(ISO)", value, "toString", qt + "ISODate")
            d.putCallItem("(SystemLocale)", value, "toString",
hjk's avatar
hjk committed
165
                qt + "SystemLocaleDate")
hjk's avatar
hjk committed
166
            d.putCallItem("(Locale)", value, "toString", qt + "LocaleDate")
hjk's avatar
hjk committed
167
168


hjk's avatar
hjk committed
169
def qdump__QTime(d, value):
170
    d.putValue(value["mds"], MillisecondsSinceMidnight)
171
    d.putNumChild(1)
hjk's avatar
hjk committed
172
    if d.isExpanded():
173
        qt = d.ns + "Qt::"
174
        # FIXME: This improperly uses complex return values.
hjk's avatar
hjk committed
175
176
177
178
        with Children(d):
            d.putCallItem("toString", value, "toString", qt + "TextDate")
            d.putCallItem("(ISO)", value, "toString", qt + "ISODate")
            d.putCallItem("(SystemLocale)", value, "toString",
hjk's avatar
hjk committed
179
                 qt + "SystemLocaleDate")
hjk's avatar
hjk committed
180
181
            d.putCallItem("(Locale)", value, "toString", qt + "LocaleDate")
            d.putCallItem("toUTC", value, "toTimeSpec", qt + "UTC")
182
183


hjk's avatar
hjk committed
184
def qdump__QDateTime(d, value):
185
186
    try:
        # Fails without debug info.
187
        p = value["d"]["d"].dereference()
188
    except:
hjk's avatar
hjk committed
189
        d.putPlainChildren(value)
190
        return
191
192
    d.putValue("%s/%s" % (p["date"]["jd"], p["time"]["mds"]),
        JulianDateAndMillisecondsSinceMidnight)
193
    d.putNumChild(1)
hjk's avatar
hjk committed
194
    if d.isExpanded():
195
        # FIXME: This improperly uses complex return values.
hjk's avatar
hjk committed
196
        with Children(d):
197
            qt = d.ns + "Qt::"
hjk's avatar
hjk committed
198
199
200
201
202
203
204
205
206
207
208
            d.putCallItem("toTime_t", value, "toTime_t")
            d.putCallItem("toString", value, "toString", qt + "TextDate")
            d.putCallItem("(ISO)", value, "toString", qt + "ISODate")
            d.putCallItem("(SystemLocale)", value, "toString", qt + "SystemLocaleDate")
            d.putCallItem("(Locale)", value, "toString", qt + "LocaleDate")
            d.putCallItem("toUTC", value, "toTimeSpec", qt + "UTC")
            d.putCallItem("toLocalTime", value, "toTimeSpec", qt + "LocalTime")


def qdump__QDir(d, value):
    d.putStringValue(value["d_ptr"]["d"].dereference()["path"])
209
    d.putNumChild(2)
hjk's avatar
hjk committed
210
211
212
213
    if d.isExpanded():
        with Children(d):
            d.putCallItem("absolutePath", value, "absolutePath")
            d.putCallItem("canonicalPath", value, "canonicalPath")
hjk's avatar
hjk committed
214
215


hjk's avatar
hjk committed
216
def qdump__QFile(d, value):
217
    ptype = lookupType(d.ns + "QFilePrivate")
hjk's avatar
hjk committed
218
    d_ptr = value["d_ptr"]["d"].dereference()
219
220
    d.putStringValue(d_ptr.cast(ptype)["fileName"])
    d.putNumChild(1)
hjk's avatar
hjk committed
221
222
223
    if d.isExpanded():
        with Children(d):
            d.putCallItem("exists", value, "exists()")
hjk's avatar
hjk committed
224
225


hjk's avatar
hjk committed
226
def qdump__QFileInfo(d, value):
227
    try:
hjk's avatar
hjk committed
228
        d.putStringValue(value["d_ptr"]["d"].dereference()["fileName"])
229
    except:
hjk's avatar
hjk committed
230
        d.putPlainChildren(value)
231
        return
232
    d.putNumChild(3)
hjk's avatar
hjk committed
233
234
235
236
237
238
239
240
241
    if d.isExpanded():
        with Children(d, childType=lookupType(d.ns + "QString")):
            d.putCallItem("absolutePath", value, "absolutePath")
            d.putCallItem("absoluteFilePath", value, "absoluteFilePath")
            d.putCallItem("canonicalPath", value, "canonicalPath")
            d.putCallItem("canonicalFilePath", value, "canonicalFilePath")
            d.putCallItem("completeBaseName", value, "completeBaseName")
            d.putCallItem("completeSuffix", value, "completeSuffix")
            d.putCallItem("baseName", value, "baseName")
242
243
            if False:
                #ifdef Q_OS_MACX
hjk's avatar
hjk committed
244
245
246
247
                d.putCallItem("isBundle", value, "isBundle")
                d.putCallItem("bundleName", value, "bundleName")
            d.putCallItem("fileName", value, "fileName")
            d.putCallItem("filePath", value, "filePath")
248
            # Crashes gdb (archer-tromey-python, at dad6b53fe)
hjk's avatar
hjk committed
249
250
251
            #d.putCallItem("group", value, "group")
            #d.putCallItem("owner", value, "owner")
            d.putCallItem("path", value, "path")
252

hjk's avatar
hjk committed
253
254
            d.putCallItem("groupid", value, "groupId")
            d.putCallItem("ownerid", value, "ownerId")
255
256

            #QFile::Permissions permissions () const
hjk's avatar
hjk committed
257
            perms = call(value, "permissions")
258
259
260
            if perms is None:
                d.putValue("<not available>")
            else:
hjk's avatar
hjk committed
261
                with SubItem(d, "permissions"):
262
263
264
                    d.putValue(" ")
                    d.putType(d.ns + "QFile::Permissions")
                    d.putNumChild(10)
hjk's avatar
hjk committed
265
                    if d.isExpanded():
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
                        with Children(d, 10):
                            perms = perms['i']
                            d.putBoolItem("ReadOwner",  perms & 0x4000)
                            d.putBoolItem("WriteOwner", perms & 0x2000)
                            d.putBoolItem("ExeOwner",   perms & 0x1000)
                            d.putBoolItem("ReadUser",   perms & 0x0400)
                            d.putBoolItem("WriteUser",  perms & 0x0200)
                            d.putBoolItem("ExeUser",    perms & 0x0100)
                            d.putBoolItem("ReadGroup",  perms & 0x0040)
                            d.putBoolItem("WriteGroup", perms & 0x0020)
                            d.putBoolItem("ExeGroup",   perms & 0x0010)
                            d.putBoolItem("ReadOther",  perms & 0x0004)
                            d.putBoolItem("WriteOther", perms & 0x0002)
                            d.putBoolItem("ExeOther",   perms & 0x0001)

            #QDir absoluteDir () const
            #QDir dir () const
hjk's avatar
hjk committed
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
            d.putCallItem("caching", value, "caching")
            d.putCallItem("exists", value, "exists")
            d.putCallItem("isAbsolute", value, "isAbsolute")
            d.putCallItem("isDir", value, "isDir")
            d.putCallItem("isExecutable", value, "isExecutable")
            d.putCallItem("isFile", value, "isFile")
            d.putCallItem("isHidden", value, "isHidden")
            d.putCallItem("isReadable", value, "isReadable")
            d.putCallItem("isRelative", value, "isRelative")
            d.putCallItem("isRoot", value, "isRoot")
            d.putCallItem("isSymLink", value, "isSymLink")
            d.putCallItem("isWritable", value, "isWritable")
            d.putCallItem("created", value, "created")
            d.putCallItem("lastModified", value, "lastModified")
            d.putCallItem("lastRead", value, "lastRead")


def qdump__QFixed(d, value):
    v = int(value["val"])
hjk's avatar
hjk committed
302
303
304
305
    d.putValue("%s/64 = %s" % (v, v/64.0))
    d.putNumChild(0)


306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# Stock gdb 7.2 seems to have a problem with types here:
#
#  echo -e "namespace N { struct S { enum E { zero, one, two }; }; }\n"\
#      "int main() { N::S::E x = N::S::one;\n return x; }" >> main.cpp
#  g++ -g main.cpp
#  gdb-7.2 -ex 'file a.out' -ex 'b main' -ex 'run' -ex 'step' \
#     -ex 'ptype N::S::E' -ex 'python print gdb.lookup_type("N::S::E")' -ex 'q'
#  gdb-7.1 -ex 'file a.out' -ex 'b main' -ex 'run' -ex 'step' \
#     -ex 'ptype N::S::E' -ex 'python print gdb.lookup_type("N::S::E")' -ex 'q'
#  gdb-cvs -ex 'file a.out' -ex 'b main' -ex 'run' -ex 'step' \
#     -ex 'ptype N::S::E' -ex 'python print gdb.lookup_type("N::S::E")' -ex 'q'
#
# gives as of 2010-11-02
#
#  type = enum N::S::E {N::S::zero, N::S::one, N::S::two} \n
hjk's avatar
hjk committed
321
322
#    Traceback (most recent call last): File "<string>", line 1,
#      in <module> RuntimeError: No type named N::S::E.
323
324
325
326
327
#  type = enum N::S::E {N::S::zero, N::S::one, N::S::two} \n  N::S::E
#  type = enum N::S::E {N::S::zero, N::S::one, N::S::two} \n  N::S::E
#
# i.e. there's something broken in stock 7.2 that is was ok in 7.1 and is ok later.

hjk's avatar
hjk committed
328
329
def qdump__QFlags(d, value):
    i = value["i"]
330
    try:
hjk's avatar
hjk committed
331
        enumType = templateArgument(value.type.unqualified(), 0)
332
333
334
        d.putValue("%s (%s)" % (i.cast(enumType), i))
    except:
        d.putValue("%s" % i)
hjk's avatar
hjk committed
335
336
337
    d.putNumChild(0)


hjk's avatar
hjk committed
338
def qdump__QHash(d, value):
hjk's avatar
hjk committed
339
340

    def hashDataFirstNode(value):
hjk's avatar
hjk committed
341
342
343
344
        val = value.cast(hashDataType)
        bucket = val["buckets"]
        e = val.cast(hashNodeType)
        for n in xrange(val["numBuckets"] - 1, -1, -1):
hjk's avatar
hjk committed
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
            n = n - 1
            if n < 0:
                break
            if bucket.dereference() != e:
                return bucket.dereference()
            bucket = bucket + 1
        return e;

    def hashDataNextNode(node):
        next = node["next"]
        if next["next"]:
            return next
        d = node.cast(hashDataType.pointer()).dereference()
        numBuckets = d["numBuckets"]
        start = (node["h"] % numBuckets) + 1
        bucket = d["buckets"] + start
361
        for n in xrange(numBuckets - start):
hjk's avatar
hjk committed
362
363
364
365
366
            if bucket.dereference() != next:
                return bucket.dereference()
            bucket += 1
        return node

hjk's avatar
hjk committed
367
368
    keyType = templateArgument(value.type, 0)
    valueType = templateArgument(value.type, 1)
hjk's avatar
hjk committed
369

hjk's avatar
hjk committed
370
371
    d_ptr = value["d"]
    e_ptr = value["e"]
372
    size = d_ptr["size"]
hjk's avatar
hjk committed
373
374
375
376

    hashDataType = d_ptr.type
    hashNodeType = e_ptr.type

377
    check(0 <= size and size <= 100 * 1000 * 1000)
378
    checkRef(d_ptr["ref"])
hjk's avatar
hjk committed
379

380
381
    d.putItemCount(size)
    d.putNumChild(size)
hjk's avatar
hjk committed
382
    if d.isExpanded():
hjk's avatar
hjk committed
383
384
        isSimpleKey = isSimpleType(keyType)
        isSimpleValue = isSimpleType(valueType)
hjk's avatar
hjk committed
385
        node = hashDataFirstNode(value)
hjk's avatar
hjk committed
386
        innerType = e_ptr.dereference().type
387
388
389
        childType = innerType
        if isSimpleKey and isSimpleValue:
            childType = isSimpleValue
hjk's avatar
hjk committed
390
        with Children(d, size, maxNumChild=1000, childType=childType):
391
392
            for i in d.childRange():
                it = node.dereference().cast(innerType)
hjk's avatar
hjk committed
393
                with SubItem(d, i):
394
                    key = it["key"]
hjk's avatar
hjk committed
395
                    val = it["value"]
396
397
                    if isSimpleKey and isSimpleValue:
                        d.putName(key)
hjk's avatar
hjk committed
398
                        d.putItem(val)
399
400
                        d.putType(valueType)
                    else:
hjk's avatar
hjk committed
401
                        d.putItem(it)
402
                node = hashDataNextNode(node)
hjk's avatar
hjk committed
403
404


hjk's avatar
hjk committed
405
406
407
408
409
def qdump__QHashNode(d, value):
    keyType = templateArgument(value.type, 0)
    valueType = templateArgument(value.type, 1)
    key = value["key"]
    val = value["value"]
hjk's avatar
hjk committed
410

411
    if isSimpleType(keyType) and isSimpleType(valueType):
hjk's avatar
hjk committed
412
413
        d.putName(key)
        d.putValue(val)
hjk's avatar
hjk committed
414
    else:
415
        d.putValue(" ")
hjk's avatar
hjk committed
416

417
    d.putNumChild(2)
hjk's avatar
hjk committed
418
    if d.isExpanded():
419
        with Children(d):
hjk's avatar
hjk committed
420
421
            d.putSubItem("key", key)
            d.putSubItem("value", val)
hjk's avatar
hjk committed
422
423


hjk's avatar
hjk committed
424
425
def qdump__QHostAddress(d, value):
    data = value["d"]["d"].dereference()
hjk's avatar
hjk committed
426
427
428
    if int(data["ipString"]["d"]["size"]):
        d.putStringValue(data["ipString"])
    else:
429
430
431
432
433
434
        a = long(data["a"])
        a, n4 = divmod(a, 256)
        a, n3 = divmod(a, 256)
        a, n2 = divmod(a, 256)
        a, n1 = divmod(a, 256)
        d.putValue("%d.%d.%d.%d" % (n1, n2, n3, n4));
hjk's avatar
hjk committed
435
    d.putNumChild(1)
hjk's avatar
hjk committed
436
    if d.isExpanded():
hjk's avatar
hjk committed
437
        with Children(d):
hjk's avatar
hjk committed
438
           d.putFields(data)
hjk's avatar
hjk committed
439
440


hjk's avatar
hjk committed
441
442
def qdump__QList(d, value):
    d_ptr = value["d"]
hjk's avatar
hjk committed
443
444
445
446
    begin = d_ptr["begin"]
    end = d_ptr["end"]
    array = d_ptr["array"]
    check(begin >= 0 and end >= 0 and end <= 1000 * 1000 * 1000)
447
448
    size = end - begin
    check(size >= 0)
hjk's avatar
hjk committed
449
450
451
    #if n > 0:
    #    checkAccess(&list.front())
    #    checkAccess(&list.back())
452
    checkRef(d_ptr["ref"])
hjk's avatar
hjk committed
453
454

    # Additional checks on pointer arrays.
hjk's avatar
hjk committed
455
    innerType = templateArgument(value.type, 0)
456
    innerTypeIsPointer = innerType.code == PointerCode \
hjk's avatar
hjk committed
457
458
459
        and str(innerType.target().unqualified()) != "char"
    if innerTypeIsPointer:
        p = gdb.Value(array).cast(innerType.pointer()) + begin
hjk's avatar
hjk committed
460
        checkPointerRange(p, min(size, 100))
hjk's avatar
hjk committed
461

462
463
    d.putItemCount(size)
    d.putNumChild(size)
hjk's avatar
hjk committed
464
    if d.isExpanded():
hjk's avatar
hjk committed
465
466
467
468
469
470
471
        innerSize = innerType.sizeof
        # The exact condition here is:
        #  QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic
        # but this data is available neither in the compiled binary nor
        # in the frontend.
        # So as first approximation only do the 'isLarge' check:
        isInternal = innerSize <= d_ptr.type.sizeof and d.isMovableType(innerType)
472
        dummyType = lookupType("void").pointer().pointer()
473
474
        innerTypePointer = innerType.pointer()
        p = gdb.Value(array).cast(dummyType) + begin
475
476
477
478
        if innerTypeIsPointer:
            inner = innerType.target()
        else:
            inner = innerType
479
        # about 0.5s / 1000 items
hjk's avatar
hjk committed
480
        with Children(d, size, maxNumChild=2000, childType=inner):
481
482
            for i in d.childRange():
                if isInternal:
hjk's avatar
hjk committed
483
                    d.putSubItem(i, p.cast(innerTypePointer).dereference())
484
                else:
hjk's avatar
hjk committed
485
                    d.putSubItem(i, p.cast(innerTypePointer.pointer()).dereference())
486
                p += 1
hjk's avatar
hjk committed
487

hjk's avatar
hjk committed
488
489
def qform__QImage():
    return "Normal,Displayed"
hjk's avatar
hjk committed
490

hjk's avatar
hjk committed
491
def qdump__QImage(d, value):
492
    try:
hjk's avatar
hjk committed
493
        painters = value["painters"]
494
    except:
hjk's avatar
hjk committed
495
        d.putPlainChildren(value)
496
        return
hjk's avatar
hjk committed
497
    check(0 <= painters and painters < 1000)
hjk's avatar
hjk committed
498
    d_ptr = value["d"]
hjk's avatar
hjk committed
499
    if isNull(d_ptr):
500
        d.putValue("(null)")
hjk's avatar
hjk committed
501
    else:
502
        checkRef(d_ptr["ref"])
503
        d.putValue("(%dx%d)" % (d_ptr["width"], d_ptr["height"]))
504
505
    bits = d_ptr["data"]
    nbytes = d_ptr["nbytes"]
506
    d.putNumChild(0)
hjk's avatar
hjk committed
507
    #d.putNumChild(1)
hjk's avatar
hjk committed
508
    if d.isExpanded():
509
        with Children(d):
hjk's avatar
hjk committed
510
            with SubItem(d, "data"):
511
                d.putNoType()
512
513
                d.putNumChild(0)
                d.putValue("size: %s bytes" % nbytes);
hjk's avatar
hjk committed
514
    format = d.currentItemFormat()
515
    if format == 1:
516
        d.putDisplay(StopDisplay)
517
    elif format == 2:
hjk's avatar
hjk committed
518
519
520
521
        if False:
            # Take four bytes at a time, this is critical for performance.
            # In fact, even four at a time is too slow beyond 100x100 or so.
            d.putField("editformat", 1)  # Magic marker for direct "QImage" data.
522
            d.put('%s="' % name)
hjk's avatar
hjk committed
523
524
525
            d.put("%08x" % int(d_ptr["width"]))
            d.put("%08x" % int(d_ptr["height"]))
            d.put("%08x" % int(d_ptr["format"]))
526
            p = bits.cast(lookupType("unsigned int").pointer())
hjk's avatar
hjk committed
527
528
529
            for i in xrange(nbytes / 4):
                d.put("%08x" % int(p.dereference()))
                p += 1
530
            d.put('",')
hjk's avatar
hjk committed
531
532
533
        else:
            # Write to an external file. Much faster ;-(
            file = tempfile.mkstemp(prefix="gdbpy_")
534
            filename = file[1].replace("\\", "\\\\")
535
            p = bits.cast(lookupType("unsigned char").pointer())
hjk's avatar
hjk committed
536
537
            gdb.execute("dump binary memory %s %s %s" %
                (filename, cleanAddress(p), cleanAddress(p + nbytes)))
538
539
            d.putDisplay(DisplayImage, " %d %d %d %s"
                % (d_ptr["width"], d_ptr["height"], d_ptr["format"], filename))
hjk's avatar
hjk committed
540
541


hjk's avatar
hjk committed
542
543
544
def qdump__QLinkedList(d, value):
    d_ptr = value["d"]
    e_ptr = value["e"]
545
    n = d_ptr["size"]
hjk's avatar
hjk committed
546
    check(0 <= n and n <= 100*1000*1000)
547
    checkRef(d_ptr["ref"])
hjk's avatar
hjk committed
548
    d.putItemCount(n)
549
    d.putNumChild(n)
hjk's avatar
hjk committed
550
551
552
    if d.isExpanded():
        innerType = templateArgument(value.type, 0)
        with Children(d, n, maxNumChild=1000, childType=innerType):
553
554
            p = e_ptr["n"]
            for i in d.childRange():
hjk's avatar
hjk committed
555
                d.putSubItem(i, p["t"])
556
                p = p["n"]
hjk's avatar
hjk committed
557

558
qqLocalesCount = None
hjk's avatar
hjk committed
559

hjk's avatar
hjk committed
560
def qdump__QLocale(d, value):
561
562
563
564
565
566
567
568
    # Check for uninitialized 'index' variable. Retrieve size of QLocale data array
    # from variable in qlocale.cpp (default: 368/Qt 4.8), 368 being 'System'.
    global qqLocalesCount
    if qqLocalesCount is None:
        try:
            qqLocalesCount = int(value(qtNamespace() + 'locale_data_size'))
        except:
            qqLocalesCount = 368
hjk's avatar
hjk committed
569
    index = int(value["p"]["index"])
570
    check(index >= 0 and index <= qqLocalesCount)
hjk's avatar
hjk committed
571
    d.putStringValue(call(value, "name"))
572
573
574
    d.putNumChild(0)
    return
    # FIXME: Poke back for variants.
hjk's avatar
hjk committed
575
576
577
578
579
580
581
    if d.isExpanded():
        with Children(d, childType=lookupType(d.ns + "QChar"), childNumChild=0):
            d.putCallItem("country", value, "country")
            d.putCallItem("language", value, "language")
            d.putCallItem("measurementSystem", value, "measurementSystem")
            d.putCallItem("numberOptions", value, "numberOptions")
            d.putCallItem("timeFormat_(short)", value,
hjk's avatar
hjk committed
582
                "timeFormat", d.ns + "QLocale::ShortFormat")
hjk's avatar
hjk committed
583
            d.putCallItem("timeFormat_(long)", value,
hjk's avatar
hjk committed
584
                "timeFormat", d.ns + "QLocale::LongFormat")
hjk's avatar
hjk committed
585
586
587
588
589
590
            d.putCallItem("decimalPoint", value, "decimalPoint")
            d.putCallItem("exponential", value, "exponential")
            d.putCallItem("percent", value, "percent")
            d.putCallItem("zeroDigit", value, "zeroDigit")
            d.putCallItem("groupSeparator", value, "groupSeparator")
            d.putCallItem("negativeSign", value, "negativeSign")
hjk's avatar
hjk committed
591
592


hjk's avatar
hjk committed
593
def qdump__QMapNode(d, value):
594
595
    d.putValue(" ")
    d.putNumChild(2)
hjk's avatar
hjk committed
596
597
598
599
600
601
602
603
604
    if d.isExpanded():
        with Children(d):
            d.putSubItem("key", value["key"])
            d.putSubItem("value", value["value"])


def qdumpHelper__QMap(d, value, forceLong):
    d_ptr = value["d"].dereference()
    e_ptr = value["e"].dereference()
hjk's avatar
hjk committed
605
606
    n = d_ptr["size"]
    check(0 <= n and n <= 100*1000*1000)
607
    checkRef(d_ptr["ref"])
hjk's avatar
hjk committed
608
609

    d.putItemCount(n)
610
    d.putNumChild(n)
hjk's avatar
hjk committed
611
    if d.isExpanded():
hjk's avatar
hjk committed
612
613
614
        if n > 1000:
            n = 1000

hjk's avatar
hjk committed
615
616
        keyType = templateArgument(value.type, 0)
        valueType = templateArgument(value.type, 1)
hjk's avatar
hjk committed
617
618
619
620
621
622
623
624
625

        isSimpleKey = isSimpleType(keyType)
        isSimpleValue = isSimpleType(valueType)

        it = e_ptr["forward"].dereference()

        # QMapPayloadNode is QMapNode except for the 'forward' member, so
        # its size is most likely the offset of the 'forward' member therein.
        # Or possibly 2 * sizeof(void *)
626
627
628
        nodeType = lookupType(d.ns + "QMapNode<%s, %s>" % (keyType, valueType))
        payloadSize = nodeType.sizeof - 2 * lookupType("void").pointer().sizeof
        charPtr = lookupType("char").pointer()
hjk's avatar
hjk committed
629

630
631
632
633
        if isSimpleKey and isSimpleValue:
            innerType = valueType
        else:
            innerType = nodeType
hjk's avatar
hjk committed
634

hjk's avatar
hjk committed
635
        with Children(d, n, childType=innerType):
636
637
638
639
            for i in xrange(n):
                itd = it.dereference()
                base = it.cast(charPtr) - payloadSize
                node = base.cast(nodeType.pointer()).dereference()
hjk's avatar
hjk committed
640
                with SubItem(d, i):
641
                    key = node["key"]
hjk's avatar
hjk committed
642
643
644
                    val = node["value"]
                    #if isSimpleType(value.type):
                    # or isStringType(d, value.type):
645
646
                    if isSimpleKey and isSimpleValue:
                        #d.putType(valueType)
hjk's avatar
hjk committed
647
648
649
650
                        if forceLong:
                            d.putName("[%s] %s" % (i, key))
                        else:
                            d.putName(key)
hjk's avatar
hjk committed
651
                        d.putItem(val)
652
                    else:
hjk's avatar
hjk committed
653
                        d.putItem(node)
654
                it = it.dereference()["forward"].dereference()
hjk's avatar
hjk committed
655
656


hjk's avatar
hjk committed
657
658
def qdump__QMap(d, value):
    qdumpHelper__QMap(d, value, False)
hjk's avatar
hjk committed
659

hjk's avatar
hjk committed
660
661
def qdump__QMultiMap(d, value):
    qdumpHelper__QMap(d, value, True)
hjk's avatar
hjk committed
662
663
664
665
666
667
668
669
670
671
672
673
674


def extractCString(table, offset):
    result = ""
    while True:
        d = table[offset]
        if d == 0:
            break
        result += "%c" % d
        offset += 1
    return result


hjk's avatar
hjk committed
675
676
def qdump__QObject(d, value):
    #warn("OBJECT: %s " % value)
677
    try:
678
        privateTypeName = d.ns + "QObjectPrivate"
679
        privateType = lookupType(privateTypeName)
hjk's avatar
hjk committed
680
681
        staticMetaObject = value["staticMetaObject"]
        d_ptr = value["d_ptr"]["d"].cast(privateType.pointer()).dereference()
682
683
        #warn("D_PTR: %s " % d_ptr)
        objectName = d_ptr["objectName"]
684
    except:
hjk's avatar
hjk committed
685
        d.putPlainChildren(value)
686
        return
hjk's avatar
hjk committed
687
    #warn("SMO: %s " % staticMetaObject)
688
689
690
691
692
693
694
    #warn("SMO DATA: %s " % staticMetaObject["d"]["stringdata"])
    superData = staticMetaObject["d"]["superdata"]
    #warn("SUPERDATA: %s" % superData)
    #while not isNull(superData):
    #    superData = superData.dereference()["d"]["superdata"]
    #    warn("SUPERDATA: %s" % superData)

695
696
    if privateType is None:
        d.putNumChild(4)
hjk's avatar
hjk committed
697
        #d.putValue(cleanAddress(value.address))
698
        d.putPlainChildren(value)
hjk's avatar
hjk committed
699
        if d.isExpanded():
700
            with Children(d):
hjk's avatar
hjk committed
701
                d.putFields(value)
702
        return
hjk's avatar
hjk committed
703
    #warn("OBJECTNAME: %s " % objectName)
704
    #warn("D_PTR: %s " % d_ptr)
hjk's avatar
hjk committed
705
    mo = d_ptr["metaObject"]
706
707
708
    if not isAccessible(mo):
        d.putInaccessible()
        return
hjk's avatar
hjk committed
709
710
711
712
713
714
    if isNull(mo):
        mo = staticMetaObject
    #warn("MO: %s " % mo)
    #warn("MO.D: %s " % mo["d"])
    metaData = mo["d"]["data"]
    metaStringData = mo["d"]["stringdata"]
715
    #extradata = mo["d"]["extradata"]   # Capitalization!
hjk's avatar
hjk committed
716
717
    #warn("METADATA: %s " % metaData)
    #warn("STRINGDATA: %s " % metaStringData)
hjk's avatar
hjk committed
718
719
    #warn("TYPE: %s " % value.type)
    #warn("INAME: %s " % d.currentIName())
720
721
    #d.putValue("")
    d.putStringValue(objectName)
hjk's avatar
hjk committed
722
    #QSignalMapper::staticMetaObject
723
    #checkRef(d_ptr["ref"])
hjk's avatar
hjk committed
724
    d.putNumChild(4)
hjk's avatar
hjk committed
725
    if d.isExpanded():
726
      with Children(d):
727

hjk's avatar
hjk committed
728
        # Local data.
729
730
        if privateTypeName != d.ns + "QObjectPrivate":
            if not privateType is None:
hjk's avatar
hjk committed
731
              with SubItem(d, "data"):
732
                d.putValue(" ")
733
                d.putNoType()
734
                d.putNumChild(1)
hjk's avatar
hjk committed
735
                if d.isExpanded():
736
                    with Children(d):
hjk's avatar
hjk committed
737
                        d.putFields(d_ptr, False)
738
739


hjk's avatar
hjk committed
740
        d.putFields(value)
741
        # Parent and children.
hjk's avatar
hjk committed
742
743
744
        if stripClassTag(str(value.type)) == d.ns + "QObject":
            d.putSubItem("parent", d_ptr["parent"])
            d.putSubItem("children", d_ptr["children"])
hjk's avatar
hjk committed
745

746
        # Properties.
hjk's avatar
hjk committed
747
        with SubItem(d, "properties"):
748
            # Prolog
749
750
            extraData = d_ptr["extraData"]   # Capitalization!
            if isNull(extraData):
751
                dynamicPropertyCount = 0
752
            else:
753
                extraDataType = lookupType(
754
755
756
757
758
759
760
761
762
                    d.ns + "QObjectPrivate::ExtraData").pointer()
                extraData = extraData.cast(extraDataType)
                ed = extraData.dereference()
                names = ed["propertyNames"]
                values = ed["propertyValues"]
                #userData = ed["userData"]
                namesBegin = names["d"]["begin"]
                namesEnd = names["d"]["end"]
                namesArray = names["d"]["array"]
763
764
                dynamicPropertyCount = namesEnd - namesBegin

hjk's avatar
hjk committed
765
            #staticPropertyCount = call(mo, "propertyCount")
766
            staticPropertyCount = metaData[6]
767
768
769
            #warn("PROPERTY COUNT: %s" % staticPropertyCount)
            propertyCount = staticPropertyCount + dynamicPropertyCount

770
            d.putNoType()
771
772
773
            d.putItemCount(propertyCount)
            d.putNumChild(propertyCount)

hjk's avatar
hjk committed
774
            if d.isExpanded():
775
776
                # FIXME: Make this global. Don't leak.
                variant = "'%sQVariant'" % d.ns
777
                # Avoid malloc symbol clash with QVector
hjk's avatar
hjk committed
778
779
                gdb.execute("set $d = (%s*)calloc(sizeof(%s), 1)"
                    % (variant, variant))
780
                gdb.execute("set $d.d.is_shared = 0")
781

hjk's avatar
hjk committed
782
                with Children(d):
783
                    # Dynamic properties.
784
785
786
787
788
789
790
791
792
793
                    if dynamicPropertyCount != 0:
                        dummyType = lookupType("void").pointer().pointer()
                        namesType = lookupType(d.ns + "QByteArray")
                        valuesBegin = values["d"]["begin"]
                        valuesEnd = values["d"]["end"]
                        valuesArray = values["d"]["array"]
                        valuesType = lookupType(d.ns + "QVariant")
                        p = namesArray.cast(dummyType) + namesBegin
                        q = valuesArray.cast(dummyType) + valuesBegin
                        for i in xrange(dynamicPropertyCount):
hjk's avatar
hjk committed
794
                            with SubItem(d, i):
795
796
797
798
799
800
                                pp = p.cast(namesType.pointer()).dereference();
                                d.putField("key", encodeByteArray(pp))
                                d.putField("keyencoded", Hex2EncodedLatin1)
                                qq = q.cast(valuesType.pointer().pointer())
                                qq = qq.dereference();
                                d.putField("addr", cleanAddress(qq))
801
802
                                d.putField("exp", "*(%s*)%s"
                                     % (variant, cleanAddress(qq)))
hjk's avatar
hjk committed
803
804
                                t = qdump__QVariant(d, qq)
                                # Override the "QVariant (foo)" output.
hjk's avatar
hjk committed
805
                                d.putBetterType(t)
806
807
                            p += 1
                            q += 1
808
809
810
811

                    # Static properties.
                    propertyData = metaData[7]
                    for i in xrange(staticPropertyCount):
812
                      with NoAddress(d):
hjk's avatar
hjk committed
813
814
815
816
817
818
                        offset = propertyData + 3 * i
                        propertyName = extractCString(metaStringData,
                                                      metaData[offset])
                        propertyType = extractCString(metaStringData,
                                                      metaData[offset + 1])
                        with SubItem(d, propertyName):
819
820
821
822
                            #flags = metaData[offset + 2]
                            #warn("FLAGS: %s " % flags)
                            #warn("PROPERTY: %s %s " % (propertyType, propertyName))
                            # #exp = '((\'%sQObject\'*)%s)->property("%s")' \
hjk's avatar
hjk committed
823
                            #     % (d.ns, value.address, propertyName)
hjk's avatar
hjk committed
824
                            #exp = '"((\'%sQObject\'*)%s)"' %
hjk's avatar
hjk committed
825
                            #(d.ns, value.address,)
826
                            #warn("EXPRESSION:  %s" % exp)
hjk's avatar
hjk committed
827
                            prop = call(value, "property",
hjk's avatar
hjk committed
828
                                str(cleanAddress(metaStringData + metaData[offset])))
hjk's avatar
hjk committed
829
                            value1 = prop["d"]
830
                            #warn("   CODE: %s" % value1["type"])
hjk's avatar
hjk committed
831
832
                            # Type 1 and 2 are bool and int.
                            # Try to save a few cycles in this case:
833
                            if int(value1["type"]) > 2:
hjk's avatar
hjk committed
834
                                # Poke back prop
hjk's avatar
hjk committed
835
836
837
838
839
840
                                gdb.execute("set $d.d.data.ull = %s"
                                        % value1["data"]["ull"])
                                gdb.execute("set $d.d.type = %s"
                                        % value1["type"])
                                gdb.execute("set $d.d.is_null = %s"
                                        % value1["is_null"])
hjk's avatar
hjk committed
841
                                prop = parseAndEvaluate("$d").dereference()
hjk's avatar
hjk committed
842
                            val, inner, innert, handled = \
hjk's avatar
hjk committed
843
                                qdumpHelper__QVariant(d, prop)
hjk's avatar
hjk committed
844
845
846
847

                            if handled:
                                pass
                            elif len(inner):
848
849
                                # Build-in types.
                                d.putType(inner)
hjk's avatar
hjk committed
850
                                d.putItem(val)
851
852
                            else:
                                # User types.
853
854
                           #    func = "typeToName(('%sQVariant::Type')%d)"
                           #       % (d.ns, variantType)
hjk's avatar
hjk committed
855
                           #    type = str(call(value, func))
856
857
                           #    type = type[type.find('"') + 1 : type.rfind('"')]
                           #    type = type.replace("Q", d.ns + "Q") # HACK!
hjk's avatar
hjk committed
858
                           #    data = call(value, "constData")
859
860
                           #    tdata = data.cast(lookupType(type).pointer())
                           #      .dereference()
861
862
863
                           #    d.putValue("(%s)" % tdata.type)
                           #    d.putType(tdata.type)
                           #    d.putNumChild(1)
hjk's avatar
hjk committed
864
                           #    if d.isExpanded():
865
                           #        with Children(d):
hjk's avatar
hjk committed
866
                           #           d.putSubItem("data", tdata)
867
                                warn("FIXME: CUSTOM QOBJECT PROPERTY: %s %s"
868
869
870
871
872
                                    % (propertyType, innert))
                                d.putType(propertyType)
                                d.putValue("...")
                                d.putNumChild(0)

873
        # Connections.
hjk's avatar
hjk committed
874
        with SubItem(d, "connections"):
875
            d.putNoType()
876
877
878
879
            connections = d_ptr["connectionLists"]
            connectionListCount = 0
            if not isNull(connections):
                connectionListCount = connections["d"]["size"]
880
            d.putItemCount(connectionListCount, 0)
881
            d.putNumChild(connectionListCount)
hjk's avatar
hjk committed
882
            if d.isExpanded():