diff options
Diffstat (limited to 'solenv/gdb/libreoffice/sw.py')
-rw-r--r-- | solenv/gdb/libreoffice/sw.py | 305 |
1 files changed, 305 insertions, 0 deletions
diff --git a/solenv/gdb/libreoffice/sw.py b/solenv/gdb/libreoffice/sw.py new file mode 100644 index 000000000..707d0a425 --- /dev/null +++ b/solenv/gdb/libreoffice/sw.py @@ -0,0 +1,305 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +import six +import gdb +from libreoffice.util import printing + +class SwPositionPrinter(object): + '''Prints SwPosition.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + node = self.value['nNode']['m_pNode'].dereference(); + block = node['m_pBlock'].dereference(); + nodeindex = block['nStart'] + node['m_nOffset'] + offset = self.value['nContent']['m_nIndex'] + return "%s (node %d, offset %d)" % (self.typename, nodeindex, offset) + +class SwNodeIndexPrinter(object): + '''Prints SwNodeIndex.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + node = self.value['m_pNode'].dereference(); + block = node['m_pBlock'].dereference(); + nodeindex = block['nStart'] + node['m_nOffset'] + return "%s (node %d)" % (self.typename, nodeindex) + +class SwIndexPrinter(object): + '''Prints SwIndex.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + offset = self.value['m_nIndex'] + return "%s (offset %d)" % (self.typename, offset) + +class SwPaMPrinter(object): + '''Prints SwPaM.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + return "%s" % (self.typename) + + def children(self): + next_ = self.value['m_pNext'] + prev = self.value['m_pPrev'] + point = self.value['m_pPoint'].dereference() + mark = self.value['m_pMark'].dereference() + children = [ ( 'point', point), ( 'mark', mark ) ] + if next_ != self.value.address: + children.append(("next", next_)) + if prev != self.value.address: + children.append(("prev", prev)) + return children.__iter__() + +# apparently the purpose of this is to suppress printing all the extra members +# that SwCursor and SwUnoCursor add +class SwUnoCursorPrinter(SwPaMPrinter): + '''Prints SwUnoCursor.''' + +class SwRectPrinter(object): + '''Prints SwRect.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + return "%s" % (self.typename) + + def children(self): + point = self.value['m_Point'] + size = self.value['m_Size'] + children = [ ( 'point', point), ( 'size', size ) ] + return children.__iter__() + +class MarkBasePrinter(object): + '''Prints sw::mark::MarkBase.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + return "%s" % (self.typename) + + def children(self): + m = self.value.cast(self.value.dynamic_type) + return [ ( v, m[ v ] ) + for v in ( 'm_aName', 'm_pPos1', 'm_pPos2' ) ].__iter__() + +class SwXTextRangeImplPrinter(object): + '''Prints SwXTextRange::Impl.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + return "%s" % (self.typename) + + def children(self): + mark = self.value['m_pMark'].dereference() + children = [('mark', mark)] + return children.__iter__() + +class SwXTextCursorPrinter(object): + '''Prints SwXTextCursor.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + return "%s" % (self.typename) + + def children(self): + cursor = self.value['m_pUnoCursor']["m_pCursor"]["_M_ptr"] + registeredIn = cursor.dereference() + children = [('m_pUnoCursor', registeredIn)] + return children.__iter__() + +class SwUnoImplPtrPrinter(object): + """Prints sw::UnoImplPtr""" + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + if self.value['m_p']: + return "%s %s" % (self.typename, self.value['m_p'].dereference()) + else: + return "empty %s" % (self.typename,) + +class SwXTextRangePrinter(object): + '''Prints SwXTextRange.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + return "%s %s" % (self.typename, self.value['m_pImpl']) + +class BigPtrArrayPrinter(object): + '''Prints BigPtrArray.''' + + def __init__(self, typename, value): + self.typename = typename + self.value = value + + def to_string(self): + length = self.value['m_nSize'] + if length > 0: + return "%s of length %d" % (self.typename, length) + else: + return "empty %s" % self.typename + + def children(self): + return self._iterator(self.value) + + def display_hint(self): + return 'array' + + + class _iterator(six.Iterator): + + def __init__(self, array): + # libstdc++ unique_ptr is a std::tuple which contains multiple + # _M_head_impl members and gdb may pick the wrong one by default + # so have to manually cast it to the one that contains the array + self.blocks = array['m_ppInf']['_M_t']['_M_t'].cast(gdb.lookup_type("std::_Head_base<0, BlockInfo**, false>"))['_M_head_impl'] + self.count = array['m_nSize'] + self.pos = 0 + self.block_count = array['m_nBlock'] + self.block_pos = 0 + self.block = None + self.indent = "" + self.max_indent = " " + self._next_block(False) + self._check_invariant() + + def __iter__(self): + return self + + def _node_value(self, node): + cur_indent = self.indent + if str(node.dynamic_type.target()) == "SwTextNode": + # accessing this is completely non-obvious... + # also, node.dynamic_cast(node.dynamic_type) is null? + value = " TextNode " + \ + six.text_type(node.cast(node.dynamic_type).dereference()['m_Text']) + elif str(node.dynamic_type.target()) == "SwOLENode": + value = " OLENode " + elif str(node.dynamic_type.target()) == "SwGrfNode": + value = " GrfNode " + elif str(node.dynamic_type.target()) == "SwSectionNode": + value = " SectionNode " + self.indent += " " + elif str(node.dynamic_type.target()) == "SwTableNode": + value = " TableNode " + self.indent += " " + elif str(node.dynamic_type.target()) == "SwStartNode": + value = " StartNode " + self.indent += " " + elif str(node.dynamic_type.target()) == "SwEndNode": + value = " EndNode " + self.indent = self.indent[:-1] + cur_indent = self.indent + elif str(node.dynamic_type.target()) == "SwDummySectionNode": + value = "DummySctNode " + else: # must be currently being deleted, so has some abstract type + value = "~DeletedNode " +# return "\n[%s%4d%s] %s %s" % (cur_indent, self.pos, \ +# self.max_indent[len(cur_indent):], node, value) + return "\n[%4d] %s%s%s %s" % (self.pos, cur_indent, \ + node, self.max_indent[len(cur_indent):], value) + + def __next__(self): + if self.pos == self.count: + raise StopIteration() + + name = str(self.pos) + node = self.block['mvData']['_M_elems'][self.pos - self.block['nStart']] + value = self._node_value(node) + if self.pos == self.block['nEnd']: + self._next_block() + self.pos += 1 + + self._check_invariant() + return (name, value) + + def _next_block(self, advance = True): + if advance: + self.block_pos += 1 + + if self.block_pos == self.block_count: + return + + pblock = self.blocks[self.block_pos] + assert pblock + block = pblock.dereference() + start = block['nStart'] + end = block['nEnd'] + assert end - start + 1 == block['nElem'] + if self.block: + assert start == self.block['nEnd'] + 1 + assert end <= self.count + else: + assert start == 0 + self.block = block + + def _check_invariant(self): + assert self.pos <= self.count + assert self.block_pos <= self.block_count + if self.pos == 0 and self.pos < self.count: + assert self.block != None + +printer = None + +def build_pretty_printers(): + global printer + + printer = printing.Printer("libreoffice/sw") + printer.add('BigPtrArray', BigPtrArrayPrinter) + printer.add('SwPosition', SwPositionPrinter) + printer.add('SwNodeIndex', SwNodeIndexPrinter) + printer.add('SwIndex', SwIndexPrinter) + printer.add('SwPaM', SwPaMPrinter) + printer.add('SwUnoCursor', SwUnoCursorPrinter) + printer.add('SwRect', SwRectPrinter) + printer.add('sw::mark::Bookmark', MarkBasePrinter) + printer.add('sw::mark::MarkBase', MarkBasePrinter) + printer.add('sw::mark::UnoMark', MarkBasePrinter) + printer.add('sw::mark::IMark', MarkBasePrinter) + printer.add('SwXTextRange::Impl', SwXTextRangeImplPrinter) + printer.add('sw::UnoImplPtr', SwUnoImplPtrPrinter) + printer.add('SwXTextRange', SwXTextRangePrinter) + printer.add('SwXTextCursor', SwXTextCursorPrinter) + +def register_pretty_printers(obj): + printing.register_pretty_printer(printer, obj) + +build_pretty_printers() + +# vim:set shiftwidth=4 softtabstop=4 expandtab: |