tdf#144694 In direct SQL dialog, activate options 'Run SQL command
[LibreOffice.git] / solenv / gdb / libreoffice / sw.py
blob1f8b8c1636e2be4d2e7f2a5fffbf46e06ffff869
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 try:
198 # supposedly works on Debian gdb 13.2
199 self.blocks = array['m_ppInf']['_M_t']['_M_t'].cast(gdb.lookup_type("std::_Head_base<0ul, BlockInfo**, false>"))['_M_head_impl']
200 except gdb.error:
201 # works on Fedora gdb 13.2
202 self.blocks = array['m_ppInf']['_M_t']['_M_t'].cast(gdb.lookup_type("std::_Head_base<0, BlockInfo**, false>"))['_M_head_impl']
203 self.count = array['m_nSize']
204 self.pos = 0
205 self.block_count = array['m_nBlock']
206 self.block_pos = 0
207 self.block = None
208 self.indent = ""
209 self.max_indent = " "
210 self._next_block(False)
211 self._check_invariant()
213 def __iter__(self):
214 return self
216 def _node_value(self, node):
217 cur_indent = self.indent
218 if str(node.dynamic_type.target()) == "SwTextNode":
219 # accessing this is completely non-obvious...
220 # also, node.dynamic_cast(node.dynamic_type) is null?
221 value = " TextNode " + \
222 six.text_type(node.cast(node.dynamic_type).dereference()['m_Text'])
223 elif str(node.dynamic_type.target()) == "SwOLENode":
224 value = " OLENode "
225 elif str(node.dynamic_type.target()) == "SwGrfNode":
226 value = " GrfNode "
227 elif str(node.dynamic_type.target()) == "SwSectionNode":
228 value = " SectionNode "
229 self.indent += " "
230 elif str(node.dynamic_type.target()) == "SwTableNode":
231 value = " TableNode "
232 self.indent += " "
233 elif str(node.dynamic_type.target()) == "SwStartNode":
234 value = " StartNode "
235 self.indent += " "
236 elif str(node.dynamic_type.target()) == "SwEndNode":
237 value = " EndNode "
238 self.indent = self.indent[:-1]
239 cur_indent = self.indent
240 elif str(node.dynamic_type.target()) == "SwDummySectionNode":
241 value = "DummySctNode "
242 else: # must be currently being deleted, so has some abstract type
243 value = "~DeletedNode "
244 # return "\n[%s%4d%s] %s %s" % (cur_indent, self.pos, \
245 # self.max_indent[len(cur_indent):], node, value)
246 return "\n[%4d] %s%s%s %s" % (self.pos, cur_indent, \
247 node, self.max_indent[len(cur_indent):], value)
249 def __next__(self):
250 if self.pos == self.count:
251 raise StopIteration()
253 name = str(self.pos)
254 node = self.block['mvData']['_M_elems'][self.pos - self.block['nStart']]
255 value = self._node_value(node)
256 if self.pos == self.block['nEnd']:
257 self._next_block()
258 self.pos += 1
260 self._check_invariant()
261 return (name, value)
263 def _next_block(self, advance = True):
264 if advance:
265 self.block_pos += 1
267 if self.block_pos == self.block_count:
268 return
270 pblock = self.blocks[self.block_pos]
271 assert pblock
272 block = pblock.dereference()
273 start = block['nStart']
274 end = block['nEnd']
275 assert end - start + 1 == block['nElem']
276 if self.block:
277 assert start == self.block['nEnd'] + 1
278 assert end <= self.count
279 else:
280 assert start == 0
281 self.block = block
283 def _check_invariant(self):
284 assert self.pos <= self.count
285 assert self.block_pos <= self.block_count
286 if self.pos == 0 and self.pos < self.count:
287 assert self.block is not None
289 printer = None
291 def build_pretty_printers():
292 global printer
294 printer = printing.Printer("libreoffice/sw")
295 printer.add('BigPtrArray', BigPtrArrayPrinter)
296 printer.add('SwPosition', SwPositionPrinter)
297 printer.add('SwNodeIndex', SwNodeIndexPrinter)
298 printer.add('SwContentIndex', SwContentIndexPrinter)
299 printer.add('SwPaM', SwPaMPrinter)
300 printer.add('SwUnoCursor', SwUnoCursorPrinter)
301 printer.add('SwRect', SwRectPrinter)
302 printer.add('sw::mark::Bookmark', MarkBasePrinter)
303 printer.add('sw::mark::MarkBase', MarkBasePrinter)
304 printer.add('sw::mark::UnoMark', MarkBasePrinter)
305 printer.add('sw::mark::IMark', MarkBasePrinter)
306 printer.add('SwXTextRange::Impl', SwXTextRangeImplPrinter)
307 printer.add('sw::UnoImplPtr', SwUnoImplPtrPrinter)
308 printer.add('SwXTextRange', SwXTextRangePrinter)
309 printer.add('SwXTextCursor', SwXTextCursorPrinter)
311 def register_pretty_printers(obj):
312 printing.register_pretty_printer(printer, obj)
314 build_pretty_printers()
316 # vim:set shiftwidth=4 softtabstop=4 expandtab: