2c524ab87e
Apparently commit ea858ca924
broke it on
Fedora 38, where i now get:
gdb.error: No type named std::_Head_base<0ul, BlockInfo**, false>.
So try both variants.
Change-Id: If344077df7a6b329286bc1296446562301305946
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154525
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
316 lines
11 KiB
Python
316 lines
11 KiB
Python
# -*- 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.lookup_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 != 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:
|