# -*- 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 SwContentIndexPrinter(object):
'''Prints SwContentIndex.'''
def __init__(self, typename, value):
self.typename = typename
self.value = value
def to_string(self):
pNode = self.value[
'm_pContentNode']
nodeindex =
'none'
if pNode:
node = pNode.dereference()
block = node[
'm_pBlock'].dereference()
nodeindex = str(block[
'nStart'] + node[
'm_nOffset'])
offset = self.value[
'm_nIndex']
return "%s (node %s offset %s)" % (self.typename, nodeindex, 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_oPos1',
'm_oPos2' ) ].__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'][
'_M_t'][
'_M_t'].cast(gdb.look
up_type("std::_Head_base<0, SwXTextRange::Impl*, false>"))['_M_head_impl'].dereference())
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
try:
# supposedly works on Debian gdb 13.2
self.blocks = array['m_ppInf']['_M_t']['_M_t'].cast(gdb.lookup_type("std::_Head_base<0ul, BlockInfo**, false>"))['_M_head_impl']
except gdb.error:
# works on Fedora gdb 13.2
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 is not 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('SwContentIndex', SwContentIndexPrinter)
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: