File: print.py

package info (click to toggle)
wxpython4.0 4.2.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 232,540 kB
  • sloc: cpp: 958,937; python: 233,059; ansic: 150,441; makefile: 51,662; sh: 8,687; perl: 1,563; javascript: 584; php: 326; xml: 200
file content (148 lines) | stat: -rwxr-xr-x 4,754 bytes parent folder | download | duplicates (6)
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)