Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / solenv / gdb / libreoffice / sw.py
blob206eda25fa18d9167f33c275b8760149f412b020
1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 import six
11 import gdb
12 from libreoffice.util import printing
14 class SwPositionPrinter(object):
15 '''Prints SwPosition.'''
17 def __init__(self, typename, value):
18 self.typename = typename
19 self.value = value
21 def to_string(self):
22 node = self.value['nNode']['m_pNode'].dereference();
23 block = node['m_pBlock'].dereference();
24 nodeindex = block['nStart'] + node['m_nOffset']
25 offset = self.value['nContent']['m_nIndex']
26 return "%s (node %d, offset %d)" % (self.typename, nodeindex, offset)
28 class SwNodeIndexPrinter(object):
29 '''Prints SwNodeIndex.'''
31 def __init__(self, typename, value):
32 self.typename = typename
33 self.value = value
35 def to_string(self):
36 node = self.value['m_pNode'].dereference();
37 block = node['m_pBlock'].dereference();
38 nodeindex = block['nStart'] + node['m_nOffset']
39 return "%s (node %d)" % (self.typename, nodeindex)
41 class SwContentIndexPrinter(object):
42 '''Prints SwContentIndex.'''
44 def __init__(self, typename, value):
45 self.typename = typename
46 self.value = value
48 def to_string(self):
49 pNode = self.value['m_pContentNode']
50 nodeindex = 'none'
51 if pNode:
52 node = pNode.dereference()
53 block = node['m_pBlock'].dereference();
54 nodeindex = str(block['nStart'] + node['m_nOffset'])
55 offset = self.value['m_nIndex']
56 return "%s (node %s offset %s)" % (self.typename, nodeindex, offset)
58 class SwPaMPrinter(object):
59 '''Prints SwPaM.'''
61 def __init__(self, typename, value):
62 self.typename = typename
63 self.value = value
65 def to_string(self):
66 return "%s" % (self.typename)
68 def children(self):
69 next_ = self.value['m_pNext']
70 prev = self.value['m_pPrev']
71 point = self.value['m_pPoint'].dereference()
72 mark = self.value['m_pMark'].dereference()
73 children = [ ( 'point', point), ( 'mark', mark ) ]
74 if next_ != self.value.address:
75 children.append(("next", next_))
76 if prev != self.value.address:
77 children.append(("prev", prev))
78 return children.__iter__()
80 # apparently the purpose of this is to suppress printing all the extra members
81 # that SwCursor and SwUnoCursor add
82 class SwUnoCursorPrinter(SwPaMPrinter):
83 '''Prints SwUnoCursor.'''
85 class SwRectPrinter(object):
86 '''Prints SwRect.'''
88 def __init__(self, typename, value):
89 self.typename = typename
90 self.value = value
92 def to_string(self):
93 return "%s" % (self.typename)
95 def children(self):
96 point = self.value['m_Point']
97 size = self.value['m_Size']
98 children = [ ( 'point', point), ( 'size', size ) ]
99 return children.__iter__()
101 class MarkBasePrinter(object):
102 '''Prints sw::mark::MarkBase.'''
104 def __init__(self, typename, value):
105 self.typename = typename
106 self.value = value
108 def to_string(self):
109 return "%s" % (self.typename)
111 def children(self):
112 m = self.value.cast(self.value.dynamic_type)
113 return [ ( v, m[ v ] )
114 for v in ( 'm_aName', 'm_oPos1', 'm_oPos2' ) ].__iter__()
116 class SwXTextRangeImplPrinter(object):
117 '''Prints SwXTextRange::Impl.'''
119 def __init__(self, typename, value):
120 self.typename = typename
121 self.value = value
123 def to_string(self):
124 return "%s" % (self.typename)
126 def children(self):
127 mark = self.value['m_pMark'].dereference()
128 children = [('mark', mark)]
129 return children.__iter__()
131 class SwXTextCursorPrinter(object):
132 '''Prints SwXTextCursor.'''
134 def __init__(self, typename, value):
135 self.typename = typename
136 self.value = value
138 def to_string(self):
139 return "%s" % (self.typename)
141 def children(self):
142 cursor = self.value['m_pUnoCursor']["m_pCursor"]["_M_ptr"]
143 registeredIn = cursor.dereference()
144 children = [('m_pUnoCursor', registeredIn)]
145 return children.__iter__()
147 class SwUnoImplPtrPrinter(object):
148 """Prints sw::UnoImplPtr"""
150 def __init__(self, typename, value):
151 self.typename = typename
152 self.value = value
154 def to_string(self):
155 if self.value['m_p']:
156 return "%s %s" % (self.typename, self.value['m_p'].dereference())
157 else:
158 return "empty %s" % (self.typename,)
160 class SwXTextRangePrinter(object):
161 '''Prints SwXTextRange.'''
163 def __init__(self, typename, value):
164 self.typename = typename
165 self.value = value
167 def to_string(self):
168 return "%s %s" % (self.typename, self.value['m_pImpl']['_M_t']['_M_t'].cast(gdb.lookup_type("std::_Head_base<0, SwXTextRange::Impl*, false>"))['_M_head_impl'].dereference())
170 class BigPtrArrayPrinter(object):
171 '''Prints BigPtrArray.'''
173 def __init__(self, typename, value):
174 self.typename = typename
175 self.value = value
177 def to_string(self):
178 length = self.value['m_nSize']
179 if length > 0:
180 return "%s of length %d" % (self.typename, length)
181 else:
182 return "empty %s" % self.typename
184 def children(self):
185 return self._iterator(self.value)
187 def display_hint(self):
188 return 'array'
191 class _iterator(six.Iterator):
193 def __init__(self, array):
194 # libstdc++ unique_ptr is a std::tuple which contains multiple
195 # _M_head_impl members and gdb may pick the wrong one by default
196 # so have to manually cast it to the one that contains the array
197 self.blocks = array['m_ppInf']['_M_t']['_M_t'].cast(gdb.lookup_type("std::_Head_base<0, BlockInfo**, false>"))['_M_head_impl']
198 self.count = array['m_nSize']
199 self.pos = 0
200 self.block_count = array['m_nBlock']
201 self.block_pos = 0
202 self.block = None
203 self.indent = ""
204 self.max_indent = " "
205 self._next_block(False)
206 self._check_invariant()
208 def __iter__(self):
209 return self
211 def _node_value(self, node):
212 cur_indent = self.indent
213 if str(node.dynamic_type.target()) == "SwTextNode":
214 # accessing this is completely non-obvious...
215 # also, node.dynamic_cast(node.dynamic_type) is null?
216 value = " TextNode " + \
217 six.text_type(node.cast(node.dynamic_type).dereference()['m_Text'])
218 elif str(node.dynamic_type.target()) == "SwOLENode":
219 value = " OLENode "
220 elif str(node.dynamic_type.target()) == "SwGrfNode":
221 value = " GrfNode "
222 elif str(node.dynamic_type.target()) == "SwSectionNode":
223 value = " SectionNode "
224 self.indent += " "
225 elif str(node.dynamic_type.target()) == "SwTableNode":
226 value = " TableNode "
227 self.indent += " "
228 elif str(node.dynamic_type.target()) == "SwStartNode":
229 value = " StartNode "
230 self.indent += " "
231 elif str(node.dynamic_type.target()) == "SwEndNode":
232 value = " EndNode "
233 self.indent = self.indent[:-1]
234 cur_indent = self.indent
235 elif str(node.dynamic_type.target()) == "SwDummySectionNode":
236 value = "DummySctNode "
237 else: # must be currently being deleted, so has some abstract type
238 value = "~DeletedNode "
239 # return "\n[%s%4d%s] %s %s" % (cur_indent, self.pos, \
240 # self.max_indent[len(cur_indent):], node, value)
241 return "\n[%4d] %s%s%s %s" % (self.pos, cur_indent, \
242 node, self.max_indent[len(cur_indent):], value)
244 def __next__(self):
245 if self.pos == self.count:
246 raise StopIteration()
248 name = str(self.pos)
249 node = self.block['mvData']['_M_elems'][self.pos - self.block['nStart']]
250 value = self._node_value(node)
251 if self.pos == self.block['nEnd']:
252 self._next_block()
253 self.pos += 1
255 self._check_invariant()
256 return (name, value)
258 def _next_block(self, advance = True):
259 if advance:
260 self.block_pos += 1
262 if self.block_pos == self.block_count:
263 return
265 pblock = self.blocks[self.block_pos]
266 assert pblock
267 block = pblock.dereference()
268 start = block['nStart']
269 end = block['nEnd']
270 assert end - start + 1 == block['nElem']
271 if self.block:
272 assert start == self.block['nEnd'] + 1
273 assert end <= self.count
274 else:
275 assert start == 0
276 self.block = block
278 def _check_invariant(self):
279 assert self.pos <= self.count
280 assert self.block_pos <= self.block_count
281 if self.pos == 0 and self.pos < self.count:
282 assert self.block != None
284 printer = None
286 def build_pretty_printers():
287 global printer
289 printer = printing.Printer("libreoffice/sw")
290 printer.add('BigPtrArray', BigPtrArrayPrinter)
291 printer.add('SwPosition', SwPositionPrinter)
292 printer.add('SwNodeIndex', SwNodeIndexPrinter)
293 printer.add('SwContentIndex', SwContentIndexPrinter)
294 printer.add('SwPaM', SwPaMPrinter)
295 printer.add('SwUnoCursor', SwUnoCursorPrinter)
296 printer.add('SwRect', SwRectPrinter)
297 printer.add('sw::mark::Bookmark', MarkBasePrinter)
298 printer.add('sw::mark::MarkBase', MarkBasePrinter)
299 printer.add('sw::mark::UnoMark', MarkBasePrinter)
300 printer.add('sw::mark::IMark', MarkBasePrinter)
301 printer.add('SwXTextRange::Impl', SwXTextRangeImplPrinter)
302 printer.add('sw::UnoImplPtr', SwUnoImplPtrPrinter)
303 printer.add('SwXTextRange', SwXTextRangePrinter)
304 printer.add('SwXTextCursor', SwXTextCursorPrinter)
306 def register_pretty_printers(obj):
307 printing.register_pretty_printer(printer, obj)
309 build_pretty_printers()
311 # vim:set shiftwidth=4 softtabstop=4 expandtab: