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

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

8
9
from __future__ import with_statement

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


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


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


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

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


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


hjk's avatar
hjk committed
52
def qform__QAbstractItemModel():
53
    return "Normal,Enhanced"
54

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

94
95
96
def qform__QModelIndex():
    return "Normal,Enhanced"

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

    try:
        # Access DisplayRole as value
hjk's avatar
hjk committed
120
121
        val = parseAndEvaluate("%s.data(%s, 0)" % (mm_, mi_))
        v = val["d"]["data"]["ptr"]
122
123
124
125
126
127
        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
128
        if d.isExpanded():
129
130
131
132
            with Children(d):
                i = 0
                for row in xrange(rowCount):
                    for column in xrange(columnCount):
hjk's avatar
hjk committed
133
                        with UnnamedSubItem(d, i):
134
135
136
                            d.putName("[%s, %s]" % (row, column))
                            mi2 = parseAndEvaluate("%s.index(%d,%d,%s)"
                                % (mm_, row, column, mi_))
hjk's avatar
hjk committed
137
                            d.putItem(mi2)
138
                            i = i + 1
hjk's avatar
hjk committed
139
140
                #d.putCallItem("parent", val, "parent")
                #with SubItem(d, "model"):
141
142
143
144
145
146
                #    d.putValue(m)
                #    d.putType(d.ns + "QAbstractItemModel*")
                #    d.putNumChild(1)
    else:
        d.putValue("(invalid)")
        d.putNumChild(0)
hjk's avatar
hjk committed
147
        if d.isExpanded():
148
149
150
151
            with Children(d):
                pass
    #gdb.execute("call free($mi)")

hjk's avatar
hjk committed
152

hjk's avatar
hjk committed
153
def qdump__QDate(d, value):
154
    d.putValue(value["jd"], JulianDate)
155
    d.putNumChild(1)
hjk's avatar
hjk committed
156
    if d.isExpanded():
157
        qt = d.ns + "Qt::"
158
        # FIXME: This improperly uses complex return values.
hjk's avatar
hjk committed
159
160
161
162
        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
163
                qt + "SystemLocaleDate")
hjk's avatar
hjk committed
164
            d.putCallItem("(Locale)", value, "toString", qt + "LocaleDate")
hjk's avatar
hjk committed
165
166


hjk's avatar
hjk committed
167
def qdump__QTime(d, value):
168
    d.putValue(value["mds"], MillisecondsSinceMidnight)
169
    d.putNumChild(1)
hjk's avatar
hjk committed
170
    if d.isExpanded():
171
        qt = d.ns + "Qt::"
172
        # FIXME: This improperly uses complex return values.
hjk's avatar
hjk committed
173
174
175
176
        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
177
                 qt + "SystemLocaleDate")
hjk's avatar
hjk committed
178
179
            d.putCallItem("(Locale)", value, "toString", qt + "LocaleDate")
            d.putCallItem("toUTC", value, "toTimeSpec", qt + "UTC")
180
181


hjk's avatar
hjk committed
182
def qdump__QDateTime(d, value):
183
184
    try:
        # Fails without debug info.
185
        p = value["d"]["d"].dereference()
186
    except:
hjk's avatar
hjk committed
187
        d.putPlainChildren(value)
188
        return
189
190
    d.putValue("%s/%s" % (p["date"]["jd"], p["time"]["mds"]),
        JulianDateAndMillisecondsSinceMidnight)
191
    d.putNumChild(1)
hjk's avatar
hjk committed
192
    if d.isExpanded():
193
        # FIXME: This improperly uses complex return values.
hjk's avatar
hjk committed
194
        with Children(d):
195
            qt = d.ns + "Qt::"
hjk's avatar
hjk committed
196
197
198
199
200
201
202
203
204
205
206
            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"])
hjk's avatar
hjk committed
207
    d.putNumChild(1)
hjk's avatar
hjk committed
208
209
210
211
    if d.isExpanded():
        with Children(d):
            d.putCallItem("absolutePath", value, "absolutePath")
            d.putCallItem("canonicalPath", value, "canonicalPath")
hjk's avatar
hjk committed
212
213


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


hjk's avatar
hjk committed
228
def qdump__QFileInfo(d, value):
229
    try:
hjk's avatar
hjk committed
230
        d.putStringValue(value["d_ptr"]["d"].dereference()["fileName"])
231
    except:
hjk's avatar
hjk committed
232
        d.putPlainChildren(value)
233
        return
hjk's avatar
hjk committed
234
    d.putNumChild(1)
hjk's avatar
hjk committed
235
236
237
238
239
240
241
242
243
    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")
244
245
            if False:
                #ifdef Q_OS_MACX
hjk's avatar
hjk committed
246
247
248
249
                d.putCallItem("isBundle", value, "isBundle")
                d.putCallItem("bundleName", value, "bundleName")
            d.putCallItem("fileName", value, "fileName")
            d.putCallItem("filePath", value, "filePath")
250
            # Crashes gdb (archer-tromey-python, at dad6b53fe)
hjk's avatar
hjk committed
251
252
253
            #d.putCallItem("group", value, "group")
            #d.putCallItem("owner", value, "owner")
            d.putCallItem("path", value, "path")
254

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

            #QFile::Permissions permissions () const
hjk's avatar
hjk committed
259
            perms = call(value, "permissions")
260
261
262
            if perms is None:
                d.putValue("<not available>")
            else:
hjk's avatar
hjk committed
263
                with SubItem(d, "permissions"):
264
265
266
                    d.putValue(" ")
                    d.putType(d.ns + "QFile::Permissions")
                    d.putNumChild(10)
hjk's avatar
hjk committed
267
                    if d.isExpanded():
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
                        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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
            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
304
305
306
307
    d.putValue("%s/64 = %s" % (v, v/64.0))
    d.putNumChild(0)


308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# 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
323
324
#    Traceback (most recent call last): File "<string>", line 1,
#      in <module> RuntimeError: No type named N::S::E.
325
326
327
328
329
#  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
330
331
def qdump__QFlags(d, value):
    i = value["i"]
332
    try:
hjk's avatar
hjk committed
333
        enumType = templateArgument(value.type.unqualified(), 0)
334
335
336
        d.putValue("%s (%s)" % (i.cast(enumType), i))
    except:
        d.putValue("%s" % i)
hjk's avatar
hjk committed
337
338
339
    d.putNumChild(0)


hjk's avatar
hjk committed
340
def qdump__QHash(d, value):
hjk's avatar
hjk committed
341
342

    def hashDataFirstNode(value):
hjk's avatar
hjk committed
343
344
345
346
        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
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
            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
363
        for n in xrange(numBuckets - start):
hjk's avatar
hjk committed
364
365
366
367
368
            if bucket.dereference() != next:
                return bucket.dereference()
            bucket += 1
        return node

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

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

    hashDataType = d_ptr.type
    hashNodeType = e_ptr.type

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

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


hjk's avatar
hjk committed
407
408
409
410
411
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
412

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

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


hjk's avatar
hjk committed
426
427
def qdump__QHostAddress(d, value):
    data = value["d"]["d"].dereference()
hjk's avatar
hjk committed
428
429
430
    if int(data["ipString"]["d"]["size"]):
        d.putStringValue(data["ipString"])
    else:
431
432
433
434
435
436
        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
437
    d.putNumChild(1)
hjk's avatar
hjk committed
438
    if d.isExpanded():
hjk's avatar
hjk committed
439
        with Children(d):
hjk's avatar
hjk committed
440
           d.putFields(data)
hjk's avatar
hjk committed
441
442


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

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

464
465
    d.putItemCount(size)
    d.putNumChild(size)
hjk's avatar
hjk committed
466
    if d.isExpanded():
hjk's avatar
hjk committed
467
468
469
470
471
472
473
        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)
474
        dummyType = lookupType("void").pointer().pointer()
475
476
        innerTypePointer = innerType.pointer()
        p = gdb.Value(array).cast(dummyType) + begin
477
478
479
480
        if innerTypeIsPointer:
            inner = innerType.target()
        else:
            inner = innerType
481
        # about 0.5s / 1000 items
hjk's avatar
hjk committed
482
        with Children(d, size, maxNumChild=2000, childType=inner):
483
484
            for i in d.childRange():
                if isInternal:
hjk's avatar
hjk committed
485
                    d.putSubItem(i, p.cast(innerTypePointer).dereference())
486
                else:
hjk's avatar
hjk committed
487
                    d.putSubItem(i, p.cast(innerTypePointer.pointer()).dereference())
488
                p += 1
hjk's avatar
hjk committed
489

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

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


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

560
qqLocalesCount = None
hjk's avatar
hjk committed
561

hjk's avatar
hjk committed
562
def qdump__QLocale(d, value):
563
564
565
566
567
568
569
570
    # 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
571
    index = int(value["p"]["index"])
572
    check(index >= 0 and index <= qqLocalesCount)
hjk's avatar
hjk committed
573
    d.putStringValue(call(value, "name"))
574
575
576
    d.putNumChild(0)
    return
    # FIXME: Poke back for variants.
hjk's avatar
hjk committed
577
578
579
580
581
582
583
    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
584
                "timeFormat", d.ns + "QLocale::ShortFormat")
hjk's avatar
hjk committed
585
            d.putCallItem("timeFormat_(long)", value,
hjk's avatar
hjk committed
586
                "timeFormat", d.ns + "QLocale::LongFormat")
hjk's avatar
hjk committed
587
588
589
590
591
592
            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
593
594


hjk's avatar
hjk committed
595
def qdump__QMapNode(d, value):
596
597
    d.putValue(" ")
    d.putNumChild(2)
hjk's avatar
hjk committed
598
599
600
601
602
603
604
605
606
    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
607
608
    n = d_ptr["size"]
    check(0 <= n and n <= 100*1000*1000)
609
    checkRef(d_ptr["ref"])
hjk's avatar
hjk committed
610
611

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

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

        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 *)
628
629
630
        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
631

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

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


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

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


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
677
678
def qdump__QObject(d, value):
    #warn("OBJECT: %s " % value)
679
    try:
680
        privateTypeName = d.ns + "QObjectPrivate"
681
        privateType = lookupType(privateTypeName)
hjk's avatar
hjk committed
682
683
        staticMetaObject = value["staticMetaObject"]
        d_ptr = value["d_ptr"]["d"].cast(privateType.pointer()).dereference()
684
685
        #warn("D_PTR: %s " % d_ptr)
        objectName = d_ptr["objectName"]
686
    except:
hjk's avatar
hjk committed
687
        d.putPlainChildren(value)
688
        return
hjk's avatar
hjk committed
689
    #warn("SMO: %s " % staticMetaObject)
690
691
692
693
694
695
696
    #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)

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

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


hjk's avatar
hjk committed
742
        d.putFields(value)
743
        # Parent and children.
hjk's avatar
hjk committed
744
745
746
        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
747

748
        # Properties.
hjk's avatar
hjk committed
749
        with SubItem(d, "properties"):
750
            # Prolog
751
752
            extraData = d_ptr["extraData"]   # Capitalization!
            if isNull(extraData):
753
                dynamicPropertyCount = 0
754
            else:
755
                extraDataType = lookupType(
756
757
758
759
760
761
762
763
764
                    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"]
765
766
                dynamicPropertyCount = namesEnd - namesBegin

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

772
            d.putNoType()
773
774
775
            d.putItemCount(propertyCount)
            d.putNumChild(propertyCount)

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

hjk's avatar
hjk committed
784
                with Children(d):
785
                    # Dynamic properties.
786
787
788
789
790
791
792
793
794
795
                    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
796
                            with SubItem(d, i):
797
798
799
800
801
802
                                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))
803
804
                                d.putField("exp", "*(%s*)%s"
                                     % (variant, cleanAddress(qq)))
hjk's avatar
hjk committed
805
806
                                t = qdump__QVariant(d, qq)
                                # Override the "QVariant (foo)" output.
hjk's avatar
hjk committed
807
                                d.putBetterType(t)
808
809
                            p += 1
                            q += 1
810
811
812
813

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

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

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