1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
###############################################################################
# Name: misc/gdb/print.py
# Purpose: pretty-printers for wx data structures: this file is meant to
# be sourced from gdb using "source -p" (or, better, autoloaded
# in the future...)
# Author: Vadim Zeitlin
# Created: 2009-01-04
# Copyright: (c) 2009 Vadim Zeitlin
# Licence: wxWindows licence
###############################################################################
# Define wxFooPrinter class implementing (at least) to_string() method for each
# wxFoo class we want to pretty print. Then just add wxFoo to the types array
# in wxLookupFunction at the bottom of this file.
import datetime
import gdb
import itertools
import sys
if sys.version_info[0] > 2:
# Python 3
Iterator = object
long = int
else:
# Python 2, we need to make an adaptor, so we can use Python 3 iterator implementations.
class Iterator:
def next(self):
return self.__next__()
# shamelessly stolen from std::string example
class wxStringPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
return self.val['m_impl']['_M_dataplus']['_M_p']
def display_hint(self):
return 'string'
class wxArrayStringPrinter:
class _iterator(Iterator):
def __init__ (self, firstItem, count):
self.item = firstItem
self.count = count
self.current = 0
def __iter__(self):
return self
def __next__(self):
current = self.current
self.current = self.current + 1
if current == self.count:
raise StopIteration
elt = self.item.dereference()
self.item = self.item + 1
return ('[%d]' % current, elt)
def __init__(self, val):
self.val = val
def children(self):
return self._iterator(self.val['m_pItems'], self.val['m_nCount'])
def to_string(self):
count = self.val['m_nCount']
capacity = self.val['m_nSize']
return ('length %d, capacity %d' % (int (count), int (capacity)))
def display_hint(self):
return 'array'
class wxDateTimePrinter:
def __init__(self, val):
self.val = val
def to_string(self):
# A value of type wxLongLong can't be used in Python arithmetic
# expressions directly so we need to convert it to long long first and
# then cast to int explicitly to be able to use it as a timestamp.
msec = self.val['m_time'].cast(gdb.lookup_type('long long'))
if msec == 0x8000000000000000:
return 'NONE'
sec = int(msec / 1000)
return datetime.datetime.fromtimestamp(sec).isoformat(' ')
class wxFileNamePrinter:
def __init__(self, val):
self.val = val
def to_string(self):
# It is simpler to just call the internal function here than to iterate
# over m_dirs array ourselves. The disadvantage of this approach is
# that it requires a live inferior process and so doesn't work when
# debugging using only a core file. If this ever becomes a serious
# problem, this should be rewritten to use m_dirs and m_name and m_ext.
return gdb.parse_and_eval('((wxFileName*)%s)->GetFullPath(0)' %
self.val.address)
class wxXYPrinterBase:
def __init__(self, val):
self.x = val['x']
self.y = val['y']
class wxPointPrinter(wxXYPrinterBase):
def to_string(self):
return '(%d, %d)' % (self.x, self.y)
class wxSizePrinter(wxXYPrinterBase):
def to_string(self):
return '%d*%d' % (self.x, self.y)
class wxRectPrinter(wxXYPrinterBase):
def __init__(self, val):
wxXYPrinterBase.__init__(self, val)
self.width = val['width']
self.height = val['height']
def to_string(self):
return '(%d, %d) %d*%d' % (self.x, self.y, self.width, self.height)
# The function looking up the pretty-printer to use for the given value.
def wxLookupFunction(val):
# Using a list is probably ok for so few items but consider switching to a
# set (or a dict and cache class types as the keys in it?) if needed later.
types = ['wxString',
'wxArrayString',
'wxDateTime',
'wxFileName',
'wxPoint',
'wxSize',
'wxRect']
for t in types:
if val.type.tag == t:
# Not sure if this is the best name to create the object of a class
# by name but at least it beats eval()
return globals()[t + 'Printer'](val)
return None
gdb.pretty_printers.append(wxLookupFunction)
|