You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2029 lines
65 KiB
2029 lines
65 KiB
From b852c77e068a8f3dedf550470be99d913241d7a8 Mon Sep 17 00:00:00 2001
|
|
From: David Tardon <dtardon@redhat.com>
|
|
Date: Fri, 29 Jul 2011 13:22:35 +0200
|
|
Subject: [PATCH 1/2] add gdb pretty printers
|
|
|
|
---
|
|
solenv/gdb/libreoffice/__init__.py | 30 ++
|
|
solenv/gdb/libreoffice/cppu.py | 164 ++++++++
|
|
solenv/gdb/libreoffice/sal.py | 121 ++++++
|
|
solenv/gdb/libreoffice/svl.py | 125 ++++++
|
|
solenv/gdb/libreoffice/sw.py | 119 ++++++
|
|
solenv/gdb/libreoffice/tl.py | 371 ++++++++++++++++++
|
|
solenv/gdb/libreoffice/util/__init__.py | 30 ++
|
|
solenv/gdb/libreoffice/util/compatibility.py | 38 ++
|
|
solenv/gdb/libreoffice/util/printing.py | 139 +++++++
|
|
solenv/gdb/libreoffice/util/string.py | 93 +++++
|
|
solenv/gdb/libreoffice/util/uno.py | 539 ++++++++++++++++++++++++++
|
|
11 files changed, 1769 insertions(+), 0 deletions(-)
|
|
create mode 100644 solenv/gdb/libreoffice/__init__.py
|
|
create mode 100644 solenv/gdb/libreoffice/cppu.py
|
|
create mode 100644 solenv/gdb/libreoffice/sal.py
|
|
create mode 100644 solenv/gdb/libreoffice/svl.py
|
|
create mode 100644 solenv/gdb/libreoffice/sw.py
|
|
create mode 100644 solenv/gdb/libreoffice/tl.py
|
|
create mode 100644 solenv/gdb/libreoffice/util/__init__.py
|
|
create mode 100644 solenv/gdb/libreoffice/util/compatibility.py
|
|
create mode 100644 solenv/gdb/libreoffice/util/printing.py
|
|
create mode 100644 solenv/gdb/libreoffice/util/string.py
|
|
create mode 100644 solenv/gdb/libreoffice/util/uno.py
|
|
|
|
diff --git a/solenv/gdb/libreoffice/__init__.py b/solenv/gdb/libreoffice/__init__.py
|
|
new file mode 100644
|
|
index 0000000..90d8012
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/__init__.py
|
|
@@ -0,0 +1,30 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/cppu.py b/solenv/gdb/libreoffice/cppu.py
|
|
new file mode 100644
|
|
index 0000000..8707ea5
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/cppu.py
|
|
@@ -0,0 +1,164 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+from libreoffice.util import printing
|
|
+from libreoffice.util.uno import TypeClass, make_uno_type, uno_cast
|
|
+
|
|
+class UnoAnyPrinter(object):
|
|
+ '''Prints UNO any'''
|
|
+
|
|
+ def __init__(self, typename, value):
|
|
+ self.value = value
|
|
+ self.typename = typename.replace('com::sun::star::', '')
|
|
+
|
|
+ def to_string(self):
|
|
+ if self._is_set():
|
|
+ return ('%s %s' % (self.typename, self._make_string()))
|
|
+ else:
|
|
+ return "empty %s" % self.typename
|
|
+
|
|
+ def _is_set(self):
|
|
+ return self.value['pType'].dereference()['eTypeClass'] != TypeClass.VOID
|
|
+
|
|
+ def _make_string(self):
|
|
+ ptr = self.value['pData']
|
|
+ assert ptr
|
|
+ type_desc = self.value['pType']
|
|
+ assert type_desc
|
|
+ type = make_uno_type(type_desc.dereference())
|
|
+ assert type
|
|
+ return str(uno_cast(type, ptr).dereference())
|
|
+
|
|
+class UnoReferencePrinter(object):
|
|
+ '''Prints reference to a UNO interface'''
|
|
+
|
|
+ def __init__(self, typename, value):
|
|
+ self.value = value
|
|
+ self.typename = typename.replace('com::sun::star::', '')
|
|
+
|
|
+ def to_string(self):
|
|
+ iface = self.value['_pInterface']
|
|
+ if iface:
|
|
+ impl = iface.cast(self._itype()).dereference()
|
|
+ return '%s to %s' % (self.typename, str(impl))
|
|
+ else:
|
|
+ return "empty %s" % self.typename
|
|
+
|
|
+ def _itype(self):
|
|
+ return self.value.type.template_argument(0).pointer()
|
|
+
|
|
+class UnoSequencePrinter(object):
|
|
+ '''Prints UNO Sequence'''
|
|
+
|
|
+ class iterator(object):
|
|
+ '''Sequence iterator'''
|
|
+
|
|
+ def __init__(self, first, size):
|
|
+ self.item = first
|
|
+ self.size = size
|
|
+ self.count = 0
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self
|
|
+
|
|
+ def next(self):
|
|
+ if self.count == self.size:
|
|
+ raise StopIteration
|
|
+ count = self.count
|
|
+ self.count = self.count + 1
|
|
+ elem = self.item.dereference()
|
|
+ self.item = self.item + 1
|
|
+ return ('[%d]' % count, elem)
|
|
+
|
|
+
|
|
+ def __init__(self, typename, value):
|
|
+ self.value = value
|
|
+ self.typename = typename.replace('com::sun::star::', '')
|
|
+
|
|
+ def to_string(self):
|
|
+ pimpl = self.value['_pSequence']
|
|
+ if pimpl:
|
|
+ impl = pimpl.dereference()
|
|
+ elems = impl['nElements']
|
|
+ if elems == 0:
|
|
+ return "empty %s" % self.typename
|
|
+ else:
|
|
+ return "%s of length %d" % (self.typename, elems)
|
|
+ else:
|
|
+ return "uninitialized %s" % self.typename
|
|
+
|
|
+ def children(self):
|
|
+ pimpl = self.value['_pSequence']
|
|
+ if pimpl:
|
|
+ impl = pimpl.dereference()
|
|
+ elemtype = self.value.type.template_argument(0)
|
|
+ elements = impl['elements'].cast(elemtype.pointer())
|
|
+ return self.iterator(elements, int(impl['nElements']))
|
|
+ else:
|
|
+ # TODO is that the best thing to do here?
|
|
+ return None
|
|
+
|
|
+ def display_hint(self):
|
|
+ if self.value['_pSequence']:
|
|
+ return 'array'
|
|
+ else:
|
|
+ return None
|
|
+
|
|
+class UnoTypePrinter(object):
|
|
+ '''Prints UNO Type'''
|
|
+
|
|
+ def __init__(self, typename, value):
|
|
+ self.value = value
|
|
+ self.typename = typename.replace('com::sun::star::', '')
|
|
+
|
|
+ def to_string(self):
|
|
+ uno = make_uno_type(self.value)
|
|
+ if uno:
|
|
+ return "%s %s" % (self.typename, uno.tag)
|
|
+ # return "%s %s" % (self.typename, uno.typename)
|
|
+ else:
|
|
+ return "invalid %s" % self.typename
|
|
+
|
|
+printer = None
|
|
+
|
|
+def build_pretty_printers():
|
|
+ global printer
|
|
+
|
|
+ printer = printing.Printer("libreoffice/cppu")
|
|
+
|
|
+ # basic UNO stuff
|
|
+ printer.add('_uno_Any', UnoAnyPrinter)
|
|
+ printer.add('com::sun::star::uno::Any', UnoAnyPrinter)
|
|
+ printer.add('com::sun::star::uno::Sequence', UnoSequencePrinter)
|
|
+ printer.add('com::sun::star::uno::Type', UnoTypePrinter)
|
|
+
|
|
+def register_pretty_printers(obj):
|
|
+ printing.register_pretty_printer(printer, obj)
|
|
+
|
|
+build_pretty_printers()
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/sal.py b/solenv/gdb/libreoffice/sal.py
|
|
new file mode 100644
|
|
index 0000000..e5a5d32
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/sal.py
|
|
@@ -0,0 +1,121 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+import gdb
|
|
+
|
|
+from libreoffice.util import printing
|
|
+from libreoffice.util.string import StringPrinterHelper
|
|
+
|
|
+class RtlStringPrinter(StringPrinterHelper):
|
|
+ '''Prints rtl_String or rtl_uString'''
|
|
+
|
|
+ def __init__(self, typename, val, encoding = None):
|
|
+ super(RtlStringPrinter, self).__init__(typename, val, encoding)
|
|
+
|
|
+ def data(self):
|
|
+ return self.val['buffer']
|
|
+
|
|
+ def length(self):
|
|
+ return self.val['length']
|
|
+
|
|
+class StringPrinter(StringPrinterHelper):
|
|
+ '''Prints rtl:: strings and string buffers'''
|
|
+
|
|
+ def __init__(self, typename, val, encoding = None):
|
|
+ super(StringPrinter, self).__init__(typename, val, encoding)
|
|
+
|
|
+ def valid(self):
|
|
+ return self.val['pData']
|
|
+
|
|
+ def data(self):
|
|
+ assert self.val['pData']
|
|
+ return self.val['pData'].dereference()['buffer']
|
|
+
|
|
+ def length(self):
|
|
+ assert self.val['pData']
|
|
+ return self.val['pData'].dereference()['length']
|
|
+
|
|
+class SalUnicodePrinter(StringPrinterHelper):
|
|
+ '''Prints a sal_Unicode*'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ super(SalUnicodePrinter, self).__init__(typename, val, 'utf-16')
|
|
+
|
|
+ def data(self):
|
|
+ return self.val
|
|
+
|
|
+ @staticmethod
|
|
+ def query(type):
|
|
+ type = type.unqualified()
|
|
+ if type.code != gdb.TYPE_CODE_PTR:
|
|
+ return False
|
|
+ return str(type.target()) == 'sal_Unicode'
|
|
+
|
|
+class RtlReferencePrinter(object):
|
|
+ '''Prints rtl::Reference'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ self.typename = typename
|
|
+ self.val = val
|
|
+
|
|
+ def to_string(self):
|
|
+ print("RtlReferencePrinter:to_string")
|
|
+ pointee = self.val['m_pBody']
|
|
+ if pointee:
|
|
+ val = pointee.dereference()
|
|
+ return '%s to %s' % (self.typename, str(val))
|
|
+ else:
|
|
+ return "empty %s" % self.typename
|
|
+
|
|
+printer = None
|
|
+
|
|
+def build_pretty_printers():
|
|
+ global printer
|
|
+
|
|
+ printer = printing.Printer("libreoffice/sal")
|
|
+
|
|
+ # strings and string buffers
|
|
+ printer.add('_rtl_String', RtlStringPrinter)
|
|
+ printer.add('_rtl_uString', lambda name, val: RtlStringPrinter(name,
|
|
+ val, 'utf-16le'))
|
|
+ printer.add('rtl::OString', StringPrinter)
|
|
+ printer.add('rtl::OUString', lambda name, val: StringPrinter(name, val, 'utf-16'))
|
|
+ printer.add('rtl::OStringBuffer', StringPrinter)
|
|
+ printer.add('rtl::OUStringBuffer', lambda name, val: StringPrinter(name, val, 'utf-16'))
|
|
+ printer.add('sal_Unicode', SalUnicodePrinter, SalUnicodePrinter.query)
|
|
+
|
|
+ # other stuff
|
|
+ printer.add('rtl::Reference', RtlReferencePrinter)
|
|
+
|
|
+ return printer
|
|
+
|
|
+def register_pretty_printers(obj):
|
|
+ printing.register_pretty_printer(printer, obj)
|
|
+
|
|
+build_pretty_printers()
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/svl.py b/solenv/gdb/libreoffice/svl.py
|
|
new file mode 100644
|
|
index 0000000..639f7c5
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/svl.py
|
|
@@ -0,0 +1,125 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+import gdb
|
|
+
|
|
+from libreoffice.util import printing
|
|
+
|
|
+class SvArrayPrinter(object):
|
|
+ '''Prints macro-declared arrays from svl module'''
|
|
+
|
|
+ def __init__(self, typename, value):
|
|
+ self.typename = typename
|
|
+ self.value = value
|
|
+
|
|
+ def to_string(self):
|
|
+ if int(self.value['nA']):
|
|
+ return "%s of length %d" % (self.typename, self.value['nA'])
|
|
+ else:
|
|
+ return "empty " + self.typename
|
|
+
|
|
+ def children(self):
|
|
+ return self._iterator(self.value['pData'], self.value['nA'])
|
|
+
|
|
+ def display_hint(self):
|
|
+ return 'array'
|
|
+
|
|
+ class _iterator(object):
|
|
+
|
|
+ def __init__(self, data, count):
|
|
+ self.data = data
|
|
+ self.count = count
|
|
+ self.pos = 0
|
|
+ self._check_invariant()
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self
|
|
+
|
|
+ def next(self):
|
|
+ if self.pos == self.count:
|
|
+ raise StopIteration()
|
|
+
|
|
+ pos = self.pos
|
|
+ elem = self.data[pos]
|
|
+ self.pos = self.pos + 1
|
|
+
|
|
+ self._check_invariant()
|
|
+ return (str(pos), elem)
|
|
+
|
|
+ def _check_invariant(self):
|
|
+ assert self.count >= 0
|
|
+ if self.count > 0:
|
|
+ assert self.data
|
|
+ assert self.pos >= 0
|
|
+ assert self.pos <= self.count
|
|
+
|
|
+ @staticmethod
|
|
+ def query(type):
|
|
+ if type.code == gdb.TYPE_CODE_REF:
|
|
+ type = type.target()
|
|
+ type = type.unqualified().strip_typedefs()
|
|
+
|
|
+ if not type.tag:
|
|
+ return False
|
|
+
|
|
+ ushort = gdb.lookup_type('sal_uInt16')
|
|
+ conforming = True
|
|
+ for field in type.fields():
|
|
+ if field.name == 'pData':
|
|
+ conforming = field.type.code == gdb.TYPE_CODE_PTR
|
|
+ elif field.name == 'nFree':
|
|
+ conforming = field.type == ushort
|
|
+ elif field.name == 'nA':
|
|
+ conforming = field.type == ushort
|
|
+ else:
|
|
+ conforming = False
|
|
+ if not conforming:
|
|
+ return False
|
|
+
|
|
+ try:
|
|
+ gdb.lookup_type('FnForEach_' + type.tag)
|
|
+ except RuntimeError:
|
|
+ return False
|
|
+
|
|
+ return True
|
|
+
|
|
+printer = None
|
|
+
|
|
+def build_pretty_printers():
|
|
+ global printer
|
|
+
|
|
+ printer = printing.Printer("libreoffice/svl")
|
|
+
|
|
+ # macro-based arrays from svl module
|
|
+ printer.add('SvArray', SvArrayPrinter, SvArrayPrinter.query)
|
|
+
|
|
+def register_pretty_printers(obj):
|
|
+ printing.register_pretty_printer(printer, obj)
|
|
+
|
|
+build_pretty_printers()
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/sw.py b/solenv/gdb/libreoffice/sw.py
|
|
new file mode 100644
|
|
index 0000000..761c153
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/sw.py
|
|
@@ -0,0 +1,119 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+from libreoffice.util import printing
|
|
+
|
|
+
|
|
+class BigPtrArrayPrinter(object):
|
|
+ '''Prints BigPtrArray.'''
|
|
+
|
|
+ def __init__(self, typename, value):
|
|
+ self.typename = typename
|
|
+ self.value = value
|
|
+
|
|
+ def to_string(self):
|
|
+ length = self.value['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(object):
|
|
+
|
|
+ def __init__(self, array):
|
|
+ self.blocks = array['ppInf']
|
|
+ self.count = array['nSize']
|
|
+ self.pos = 0
|
|
+ self.block_count = array['nBlock']
|
|
+ self.block_pos = 0
|
|
+ self.block = None
|
|
+ self._next_block(False)
|
|
+ self._check_invariant()
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self
|
|
+
|
|
+ def next(self):
|
|
+ if self.pos == self.count:
|
|
+ raise StopIteration()
|
|
+
|
|
+ name = str(self.pos)
|
|
+ value = self.block['pData'][self.pos - self.block['nStart']]
|
|
+ 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)
|
|
+
|
|
+def register_pretty_printers(obj):
|
|
+ printing.register_pretty_printer(printer, obj)
|
|
+
|
|
+build_pretty_printers()
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/tl.py b/solenv/gdb/libreoffice/tl.py
|
|
new file mode 100644
|
|
index 0000000..62c5ff5
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/tl.py
|
|
@@ -0,0 +1,371 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+import gdb
|
|
+
|
|
+from libreoffice.util import printing
|
|
+from libreoffice.util.string import StringPrinterHelper
|
|
+
|
|
+class StringPrinter(StringPrinterHelper):
|
|
+ '''Prints ByteString or UniString'''
|
|
+
|
|
+ def __init__(self, typename, val, encoding = None):
|
|
+ super(StringPrinter, self).__init__(typename, val, encoding)
|
|
+
|
|
+ def valid(self):
|
|
+ data = self.val['mpData']
|
|
+ # mnRefCount is not a good indicator: it seems there could be
|
|
+ # cases where it is negative (-7FFFFFED)
|
|
+ return data #and data.dereference()['mnRefCount'] > 0
|
|
+
|
|
+ def data(self):
|
|
+ assert self.val['mpData']
|
|
+ return self.val['mpData'].dereference()['maStr']
|
|
+
|
|
+ def length(self):
|
|
+ assert self.val['mpData']
|
|
+ return self.val['mpData'].dereference()['mnLen']
|
|
+
|
|
+class BigIntPrinter(object):
|
|
+ '''Prints big integer'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ self.val = val
|
|
+
|
|
+ def to_string(self):
|
|
+ if self.val['bIsSet']:
|
|
+ if self.val['bIsBig']:
|
|
+ return self._value()
|
|
+ else:
|
|
+ return self.val['nVal']
|
|
+ else:
|
|
+ return "unset %s" % self.typename
|
|
+
|
|
+ def _value(self):
|
|
+ len = self.val['nLen']
|
|
+ digits = self.val['nNum']
|
|
+ dsize = digits.dereference().type.sizeof * 8
|
|
+ num = 0
|
|
+ # The least significant byte is on index 0
|
|
+ for i in reversed(range(0, len)):
|
|
+ num <<= dsize
|
|
+ num += digits[i]
|
|
+ return num
|
|
+
|
|
+class ColorPrinter(object):
|
|
+ '''Prints color as rgb(r, g, b) or rgba(r, g, b, a)'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ self.val = val
|
|
+
|
|
+ def to_string(self):
|
|
+ color = self.val['mnColor']
|
|
+ b = color & 0xff
|
|
+ g = (color >> 8) & 0xff
|
|
+ r = (color >> 16) & 0xff
|
|
+ a = (color >> 24) & 0xff
|
|
+ if a:
|
|
+ return "rgba(%d, %d, %d, %d)" % (r, g, b, a)
|
|
+ else:
|
|
+ return "rgb(%d, %d, %d)" % (r, g, b)
|
|
+
|
|
+class FractionPrinter(object):
|
|
+ '''Prints fraction'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ self.typename = typename
|
|
+ self.val = val
|
|
+
|
|
+ def to_string(self):
|
|
+ numerator = self.val['nNumerator']
|
|
+ denominator = self.val['nDenominator']
|
|
+ if denominator > 0:
|
|
+ return "%d/%d" % (numerator, denominator)
|
|
+ else:
|
|
+ return "invalid %s" % self.typename
|
|
+
|
|
+class DateTimeImpl(object):
|
|
+
|
|
+ def __init__(self, date, time):
|
|
+ self.date = date
|
|
+ self.time = time
|
|
+
|
|
+ def __str__(self):
|
|
+ result = ''
|
|
+ if self.date:
|
|
+ result += str(self.date)
|
|
+ if self.time:
|
|
+ result += ' '
|
|
+ if self.time:
|
|
+ result += str(self.time)
|
|
+ return result
|
|
+
|
|
+ @staticmethod
|
|
+ def parse(val):
|
|
+ return DateTimeImpl(DateImpl.parse(val), TimeImpl.parse(val))
|
|
+
|
|
+class DateTimePrinter(object):
|
|
+ '''Prints date and time'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ self.val = val
|
|
+
|
|
+ def to_string(self):
|
|
+ return str(DateTimeImpl.parse(self.val))
|
|
+
|
|
+class DateImpl(DateTimeImpl):
|
|
+
|
|
+ def __init__(self, year, month, day):
|
|
+ super(DateImpl, self).__init__(self, None)
|
|
+ self.year = year
|
|
+ self.month = month
|
|
+ self.day = day
|
|
+
|
|
+ def __str__(self):
|
|
+ return "%d-%d-%d" % (self.year, self.month, self.day)
|
|
+
|
|
+ @staticmethod
|
|
+ def parse(val):
|
|
+ date = val['nDate']
|
|
+ d = date % 100
|
|
+ m = (date / 100) % 100
|
|
+ y = date / 10000
|
|
+ return DateImpl(y, m, d)
|
|
+
|
|
+class DatePrinter(object):
|
|
+ '''Prints date'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ self.val = val
|
|
+
|
|
+ def to_string(self):
|
|
+ return str(DateImpl.parse(self.val))
|
|
+
|
|
+class TimeImpl(DateTimeImpl):
|
|
+
|
|
+ def __init__(self, hour, minute, second, hundreth_of_second = 0):
|
|
+ super(TimeImpl, self).__init__(None, self)
|
|
+ self.hour = hour
|
|
+ self.minute = minute
|
|
+ self.second = second
|
|
+ self.hundreth_of_second = hundreth_of_second
|
|
+
|
|
+ def __str__(self):
|
|
+ decimal = ''
|
|
+ if self.hundreth_of_second != 0:
|
|
+ decimal = '.%d' % self.hundreth_of_second
|
|
+ return "%d:%d:%d%s" % (self.hour, self.minute, self.second, decimal)
|
|
+
|
|
+ @staticmethod
|
|
+ def parse(val):
|
|
+ time = val['nTime']
|
|
+ h = time / 1000000
|
|
+ m = (time / 10000) % 100
|
|
+ s = (time / 100) % 100
|
|
+ s_100 = time % 100
|
|
+ return TimeImpl(h, m, s, s_100)
|
|
+
|
|
+class TimePrinter(object):
|
|
+ '''Prints time'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ self.val = val
|
|
+
|
|
+ def to_string(self):
|
|
+ return str(TimeImpl.parse(self.val))
|
|
+
|
|
+class IteratorHelper(object):
|
|
+ '''Implements a container iterator useable for both 'linear'
|
|
+ containers (like DynArray or List) and Tables
|
|
+ '''
|
|
+
|
|
+ def __init__(self, block, count, type = None):
|
|
+ self.count = count
|
|
+ self.type = type
|
|
+ self.pos = 0
|
|
+ self.block = None
|
|
+ self.block_count = 0
|
|
+ self.block_pos = 0
|
|
+ if block:
|
|
+ self._next_block(block)
|
|
+
|
|
+ self._check_invariant()
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self
|
|
+
|
|
+ def next(self):
|
|
+ if self.pos == self.count:
|
|
+ raise StopIteration()
|
|
+
|
|
+ if self.block_pos == self.block_count:
|
|
+ self._next_block(self.block['pNext'])
|
|
+
|
|
+ name = self.name()
|
|
+ val = self.value()
|
|
+ self.advance()
|
|
+
|
|
+ self._check_invariant()
|
|
+ return (name, val)
|
|
+
|
|
+ def _next_block(self, block):
|
|
+ assert block
|
|
+
|
|
+ self.block = block.dereference()
|
|
+ self.block_pos = 0
|
|
+ self.block_count = block['nCount']
|
|
+
|
|
+ assert self.block_count <= block['nSize']
|
|
+ assert self.block_count + self.pos <= self.count
|
|
+
|
|
+ def _check_invariant(self):
|
|
+ assert self.count >= 0
|
|
+ assert self.pos >= 0
|
|
+ assert self.pos <= self.count
|
|
+ assert self.block_count >= 0
|
|
+ if self.pos < self.count:
|
|
+ assert self.block_count > 0
|
|
+ assert self.block != None
|
|
+ assert self.block_count <= self.count
|
|
+ assert self.block_pos >= 0
|
|
+ assert self.block_pos <= self.block_count
|
|
+
|
|
+class NoItemType(Exception):
|
|
+ pass
|
|
+
|
|
+class ContainerHelper(object):
|
|
+ '''Provides support for specialized container printers'''
|
|
+
|
|
+ def __init__(self, typename, val, iterator):
|
|
+ self.typename = typename
|
|
+ self.val = val
|
|
+ self.iterator = iterator
|
|
+
|
|
+ def to_string(self):
|
|
+ size = self.val['nCount']
|
|
+ if size > 0:
|
|
+ return "%s of length %d" % (self.typename, size)
|
|
+ elif size == 0:
|
|
+ return "empty %s" % self.typename
|
|
+ else:
|
|
+ return "invalid %s" % self.typename
|
|
+
|
|
+ def children(self):
|
|
+ count = self.val.cast(gdb.lookup_type('Container'))['nCount']
|
|
+ return self.iterator(self.val['pFirstBlock'], count)
|
|
+
|
|
+class LinearIterator(IteratorHelper):
|
|
+ '''Is iterator for 'linear' container'''
|
|
+
|
|
+ def __init__(self, block, count, type = None):
|
|
+ super(LinearIterator, self).__init__(block, count, type)
|
|
+
|
|
+ def name(self):
|
|
+ return str(self.pos)
|
|
+
|
|
+ def value(self):
|
|
+ nodes = self.block['pNodes']#.cast(self.type.pointer())
|
|
+ return nodes[self.block_pos]
|
|
+
|
|
+ def advance(self):
|
|
+ self.pos += 1
|
|
+ self.block_pos += 1
|
|
+
|
|
+class LinearContainerPrinter(ContainerHelper):
|
|
+ '''Prints 'linear' container, like DynArray or List'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ super(LinearContainerPrinter, self).__init__(typename, val, LinearIterator)
|
|
+
|
|
+ def display_hint(self):
|
|
+ return 'array'
|
|
+
|
|
+class TableIterator(IteratorHelper):
|
|
+ '''Is iterator for Table'''
|
|
+
|
|
+ def __init__(self, block, count, type = None):
|
|
+ super(TableIterator, self).__init__(block, count, type)
|
|
+ # ULONG doesn't work on 64-bit for some reason (gdb says it has
|
|
+ # size 4 and it's not a typedef to sal_uIntPtr)
|
|
+ self._key_type = gdb.lookup_type('sal_uIntPtr')
|
|
+ self.is_key = True
|
|
+
|
|
+ def name(self):
|
|
+ return ''
|
|
+
|
|
+ def value(self):
|
|
+ nodes = self.block['pNodes']#.cast(self.type.pointer())
|
|
+ val = nodes[self.block_pos]
|
|
+ if self.is_key:
|
|
+ val = str(val.cast(self._key_type))
|
|
+ return val
|
|
+
|
|
+ def advance(self):
|
|
+ self.pos += 1
|
|
+ self.block_pos += 1
|
|
+ self.is_key = not self.is_key
|
|
+
|
|
+class TablePrinter(ContainerHelper):
|
|
+ '''Prints table'''
|
|
+
|
|
+ def __init__(self, typename, val):
|
|
+ super(TablePrinter, self).__init__(typename, val, TableIterator)
|
|
+
|
|
+ def display_hint(self):
|
|
+ return 'map'
|
|
+
|
|
+printer = None
|
|
+
|
|
+def build_pretty_printers():
|
|
+ global printer
|
|
+
|
|
+ printer = printing.Printer('libreoffice/tl')
|
|
+
|
|
+ # old-style strings
|
|
+ printer.add('ByteString', StringPrinter)
|
|
+ printer.add('String', lambda name, val: StringPrinter(name, val, 'utf-16'))
|
|
+
|
|
+ # old-style containers
|
|
+ printer.add('DynArray', LinearContainerPrinter)
|
|
+ printer.add('List', LinearContainerPrinter)
|
|
+ printer.add('Stack', LinearContainerPrinter)
|
|
+ printer.add('Table', TablePrinter)
|
|
+
|
|
+ # various types
|
|
+ printer.add('BigInt', BigIntPrinter)
|
|
+ printer.add('Color', ColorPrinter)
|
|
+ printer.add('Fraction', FractionPrinter)
|
|
+ printer.add('DateTime', DateTimePrinter)
|
|
+ printer.add('Date', DatePrinter)
|
|
+ printer.add('Time', TimePrinter)
|
|
+
|
|
+def register_pretty_printers(obj):
|
|
+ printing.register_pretty_printer(printer, obj)
|
|
+
|
|
+build_pretty_printers()
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/util/__init__.py b/solenv/gdb/libreoffice/util/__init__.py
|
|
new file mode 100644
|
|
index 0000000..90d8012
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/util/__init__.py
|
|
@@ -0,0 +1,30 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/util/compatibility.py b/solenv/gdb/libreoffice/util/compatibility.py
|
|
new file mode 100644
|
|
index 0000000..3011f93
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/util/compatibility.py
|
|
@@ -0,0 +1,38 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+import gdb
|
|
+
|
|
+use_gdb_printing = True
|
|
+try:
|
|
+ import gdb.printing
|
|
+except ImportError:
|
|
+ use_gdb_printing = False
|
|
+
|
|
+use_lazy_string = hasattr(gdb.Value, 'lazy_string')
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/util/printing.py b/solenv/gdb/libreoffice/util/printing.py
|
|
new file mode 100644
|
|
index 0000000..e1f55b3
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/util/printing.py
|
|
@@ -0,0 +1,139 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+from collections import Mapping
|
|
+import gdb
|
|
+import re
|
|
+
|
|
+from libreoffice.util.compatibility import use_gdb_printing
|
|
+
|
|
+class SimplePrinter(object):
|
|
+
|
|
+ def __init__(self, name, function):
|
|
+ self.name = name
|
|
+ self.function = function
|
|
+ self.enabled = True
|
|
+
|
|
+ def invoke(self, val):
|
|
+ if not self.enabled:
|
|
+ return None
|
|
+ return self.function(self.name, val)
|
|
+
|
|
+class NameLookup(Mapping):
|
|
+
|
|
+ def __init__(self):
|
|
+ self.map = {}
|
|
+ self.name_regex = re.compile('^([\w:]+)(<.*>)?')
|
|
+
|
|
+ def add(self, name, printer):
|
|
+ self.map[name] = printer
|
|
+
|
|
+ def __len__(self):
|
|
+ return len(self.map)
|
|
+
|
|
+ def __getitem__(self, type):
|
|
+ typename = self._basic_type(type)
|
|
+ if typename and typename in self.map:
|
|
+ return self.map[typename]
|
|
+ return None
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self.map
|
|
+
|
|
+ def _basic_type(self, type):
|
|
+ basic_type = self.basic_type(type)
|
|
+ if basic_type:
|
|
+ match = self.name_regex.match(basic_type)
|
|
+ if match:
|
|
+ return match.group(1)
|
|
+ return None
|
|
+
|
|
+ @staticmethod
|
|
+ def basic_type(type):
|
|
+ if type.code == gdb.TYPE_CODE_REF:
|
|
+ type = type.target()
|
|
+ type = type.unqualified().strip_typedefs()
|
|
+ return type.tag
|
|
+
|
|
+class FunctionLookup(Mapping):
|
|
+
|
|
+ def __init__(self):
|
|
+ self.map = {}
|
|
+
|
|
+ def add(self, test, printer):
|
|
+ self.map[test] = printer
|
|
+
|
|
+ def __len__(self):
|
|
+ return len(self.map)
|
|
+
|
|
+ def __getitem__(self, type):
|
|
+ for (test, printer) in self.map.iteritems():
|
|
+ if test(type):
|
|
+ return printer
|
|
+ return None
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self.map
|
|
+
|
|
+class Printer(object):
|
|
+
|
|
+ def __init__(self, name):
|
|
+ self.name = name
|
|
+ self.subprinters = []
|
|
+ self.name_lookup = NameLookup()
|
|
+ self.func_lookup = FunctionLookup()
|
|
+ self.enabled = True
|
|
+
|
|
+ def add(self, name, function, lookup = None):
|
|
+ printer = SimplePrinter(name, function)
|
|
+ self.subprinters.append(printer)
|
|
+ if not lookup:
|
|
+ self.name_lookup.add(name, printer)
|
|
+ else:
|
|
+ self.func_lookup.add(lookup, printer)
|
|
+
|
|
+
|
|
+ def __call__(self, val):
|
|
+ printer = self.name_lookup[val.type]
|
|
+ if not printer:
|
|
+ printer = self.func_lookup[val.type]
|
|
+
|
|
+ if printer:
|
|
+ return printer.invoke(val)
|
|
+ return None
|
|
+
|
|
+def register_pretty_printer(printer, obj):
|
|
+ '''Registers printer with objfile'''
|
|
+
|
|
+ if use_gdb_printing:
|
|
+ gdb.printing.register_pretty_printer(obj, printer)
|
|
+ else:
|
|
+ if obj is None:
|
|
+ obj = gdb
|
|
+ obj.pretty_printers.append(printer)
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/util/string.py b/solenv/gdb/libreoffice/util/string.py
|
|
new file mode 100644
|
|
index 0000000..e2db622
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/util/string.py
|
|
@@ -0,0 +1,93 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+import gdb
|
|
+
|
|
+from libreoffice.util.compatibility import use_lazy_string
|
|
+
|
|
+class StringPrinterHelper(object):
|
|
+ '''Base for all string pretty printers'''
|
|
+
|
|
+ class MustBeImplemented(Exception):
|
|
+ pass
|
|
+
|
|
+ def __init__(self, typename, val, encoding = None):
|
|
+ self.typename = typename
|
|
+ self.val = val
|
|
+ self.encoding = encoding
|
|
+
|
|
+ def to_string(self):
|
|
+ data = self.data()
|
|
+ len = self.length()
|
|
+ if self.valid():
|
|
+ return self.make_string(data, self.encoding, len)
|
|
+ else:
|
|
+ return "unintialized %s" % self.typename
|
|
+
|
|
+ def display_hint(self):
|
|
+ if self.valid():
|
|
+ return 'string'
|
|
+ else:
|
|
+ return None
|
|
+
|
|
+ def valid(self):
|
|
+ return True
|
|
+
|
|
+ def data(self):
|
|
+ raise self.MustBeImplemented()
|
|
+
|
|
+ def length(self):
|
|
+ return -1
|
|
+
|
|
+ @staticmethod
|
|
+ def make_string(data, encoding = None, length = -1):
|
|
+ '''Creates a new string from memory'''
|
|
+
|
|
+ if not encoding:
|
|
+ encoding = ''
|
|
+
|
|
+ if use_lazy_string:
|
|
+ return data.lazy_string(encoding, length)
|
|
+
|
|
+ # we need to determine length, if not given (for sal_Unicode*)
|
|
+ if length < 0:
|
|
+ length = 0
|
|
+ while data[length] != 0 and length <= 512: # arbitrary limit
|
|
+ length += 1
|
|
+
|
|
+ # The gdb.Value.string() conversion works on array of bytes, but
|
|
+ # the length we have is the length of the string. So we must
|
|
+ # multiply it by width of character if the string is Unicode.
|
|
+ width = data[0].type.sizeof
|
|
+ if width > 1:
|
|
+ length = length * width
|
|
+
|
|
+ char = gdb.lookup_type('char')
|
|
+ bytes = data.cast(char.pointer())
|
|
+ return bytes.string(encoding, length = length)
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/libreoffice/util/uno.py b/solenv/gdb/libreoffice/util/uno.py
|
|
new file mode 100644
|
|
index 0000000..23cf06a
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/libreoffice/util/uno.py
|
|
@@ -0,0 +1,539 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+import gdb
|
|
+import re
|
|
+
|
|
+class UnsupportedType(Exception):
|
|
+ '''Represents exception thrown when an unsupported UNO type(like
|
|
+ array or union) is used.'''
|
|
+
|
|
+ def __init__(self, type):
|
|
+ self.type = type
|
|
+
|
|
+class UnknownType(Exception):
|
|
+ '''Represents exception thrown when an unknown UNO type is used.'''
|
|
+
|
|
+ def __init__(self, type):
|
|
+ self.type = type
|
|
+
|
|
+class TypeClass(object):
|
|
+ '''Represents type class of UNO type.'''
|
|
+
|
|
+ # type class of void
|
|
+ VOID = 0
|
|
+ # type class of char
|
|
+ CHAR = 1
|
|
+ # type class of boolean
|
|
+ BOOLEAN = 2
|
|
+ # type class of byte
|
|
+ BYTE = 3
|
|
+ # type class of short
|
|
+ SHORT = 4
|
|
+ # type class of unsigned short
|
|
+ UNSIGNED_SHORT = 5
|
|
+ # type class of long
|
|
+ LONG = 6
|
|
+ # type class of unsigned long
|
|
+ UNSIGNED_LONG = 7
|
|
+ # type class of hyper
|
|
+ HYPER = 8
|
|
+ # type class of unsigned hyper
|
|
+ UNSIGNED_HYPER = 9
|
|
+ # type class of float
|
|
+ FLOAT = 10
|
|
+ # type class of double
|
|
+ DOUBLE = 11
|
|
+ # type class of string
|
|
+ STRING = 12
|
|
+ # type class of type
|
|
+ TYPE = 13
|
|
+ # type class of any
|
|
+ ANY = 14
|
|
+ # type class of enum
|
|
+ ENUM = 15
|
|
+ # type class of typedef
|
|
+ TYPEDEF = 16
|
|
+ # type class of struct
|
|
+ STRUCT = 17
|
|
+ # type class of union (not implemented)
|
|
+ UNION = 18
|
|
+ # type class of exception
|
|
+ EXCEPTION = 19
|
|
+ # type class of sequence
|
|
+ SEQUENCE = 20
|
|
+ # type class of array (not implemented)
|
|
+ ARRAY = 21
|
|
+ # type class of interface
|
|
+ INTERFACE = 22
|
|
+ # type class of service (not implemented)
|
|
+ SERVICE = 23
|
|
+ # type class of module (not implemented)
|
|
+ MODULE = 24
|
|
+ # type class of interface method
|
|
+ INTERFACE_METHOD = 25
|
|
+ # type class of interface attribute
|
|
+ INTERFACE_ATTRIBUTE = 26
|
|
+ # type class of unknown type
|
|
+ UNKNOWN = 27
|
|
+ # type class of properties
|
|
+ PROPERTY = 28
|
|
+ # type class of constants
|
|
+ CONSTANT = 29
|
|
+ # type class of constants groups
|
|
+ CONSTANTS = 30
|
|
+ # type class of singletons
|
|
+ SINGLETON = 31
|
|
+
|
|
+class TemplateType(object):
|
|
+
|
|
+ def __init__(self, template, *args):
|
|
+ self.template = template
|
|
+ self.args = args
|
|
+
|
|
+ def __str__(self):
|
|
+ argtypes = [str(gdb.lookup_type(arg).strip_typedefs()) for arg in self.args]
|
|
+ return self.template + '<' + ', '.join(argtypes) + '>'
|
|
+
|
|
+class Type(object):
|
|
+ '''Describes a UNO type.'''
|
|
+
|
|
+ def __init__(self, typeclass, tag):
|
|
+ '''Constructs a new Type.
|
|
+ @param[in] typeclass value of com::sun::star::uno::TypeClass
|
|
+ @param[in] tag UNO name of the type
|
|
+ '''
|
|
+ self.typeclass = typeclass
|
|
+ self.tag = tag
|
|
+ # C++ name of the type
|
|
+ self.typename = None
|
|
+
|
|
+ def type(self):
|
|
+ '''Gets gdb.Type for the type'''
|
|
+ if self.typename:
|
|
+ return gdb.lookup_type(str(self.typename))
|
|
+ return None
|
|
+
|
|
+ @staticmethod
|
|
+ def uno2cpp(typename):
|
|
+ return str(typename).replace('.', '::')[1:-1]
|
|
+
|
|
+ def strip_typedefs(self):
|
|
+ copy = self.copy()
|
|
+ copy.typename = self._strip_typedefs(self.typename)
|
|
+ return copy
|
|
+
|
|
+ def _strip_typedefs(self, typename):
|
|
+ template_args = re.compile('([^<]+)(<.*>)')
|
|
+ match = template_args.match(typename)
|
|
+ type = self._lookup_type(match.group(1))
|
|
+ types = []
|
|
+ if match.group(2):
|
|
+ list_delim = re.compile(', *')
|
|
+ # FIXME: this does not work with nested templates
|
|
+ for arg in match.group(2).split(list_delim):
|
|
+ types.append(self._lookup_type(arg))
|
|
+
|
|
+ typename = str(type)
|
|
+ if not types.empty():
|
|
+ typename += '<' + types.join(', ') + '>'
|
|
+
|
|
+ return typename
|
|
+
|
|
+ def _lookup_type(self, typename):
|
|
+ if typename != '':
|
|
+ type = gdb.lookup_type(typename)
|
|
+ if type:
|
|
+ type = type.strip_typedefs()
|
|
+ return type
|
|
+
|
|
+def make_uno_type(val):
|
|
+ '''Creates a UNO type from gdb.Value of type
|
|
+ com::sun::star::uno::Type, typelib_TypeDescription, or
|
|
+ typelib_TypeDescriptionReference
|
|
+ '''
|
|
+
|
|
+ cssu_type = 'com::sun::star::uno::Type'
|
|
+ type_desc = '_typelib_TypeDescription'
|
|
+ type_descs =(
|
|
+ type_desc,
|
|
+ '_typelib_CompoundTypeDescription',
|
|
+ '_typelib_StructTypeDescription',
|
|
+ '_typelib_IndirectTypeDescription',
|
|
+ '_typelib_EnumTypeDescription',
|
|
+ '_typelib_InterfaceMemberTypeDescription',
|
|
+ '_typelib_InterfaceMethodTypeDescription',
|
|
+ '_typelib_InterfaceAttributeTypeDescription',
|
|
+ '_typelib_InterfaceTypeDescription'
|
|
+ )
|
|
+ type_desc_ref = '_typelib_TypeDescriptionReference'
|
|
+
|
|
+ type = val.type.strip_typedefs()
|
|
+
|
|
+ if type.tag == cssu_type:
|
|
+ pvalue = val['_pType']
|
|
+ assert pvalue
|
|
+ val = pvalue.dereference()
|
|
+ type = val.type.strip_typedefs()
|
|
+
|
|
+ while type.tag == type_desc_ref:
|
|
+ pvalue = val['pType']
|
|
+ assert pvalue
|
|
+ val = pvalue.dereference()
|
|
+ type = val.type.strip_typedefs()
|
|
+
|
|
+ if type.tag not in type_descs:
|
|
+ return None
|
|
+
|
|
+ # determination of the UNO type
|
|
+ full_val = val
|
|
+ if type.tag != type_desc:
|
|
+ while 'aBase' in val:
|
|
+ val = val['aBase']
|
|
+ type_class = int(val['eTypeClass'])
|
|
+ name = val['pTypeName'].dereference()
|
|
+ uno_type = None
|
|
+ if type_class == TypeClass.VOID:
|
|
+ uno_type = VoidType()
|
|
+ elif type_class == TypeClass.CHAR:
|
|
+ uno_type = PrimitiveType(type_class, name, 'sal_Char')
|
|
+ elif type_class == TypeClass.BOOLEAN:
|
|
+ uno_type = PrimitiveType(type_class, name, 'sal_Bool')
|
|
+ elif type_class == TypeClass.BYTE:
|
|
+ uno_type = PrimitiveType(type_class, name, 'sal_Int8')
|
|
+ elif type_class == TypeClass.SHORT:
|
|
+ uno_type = PrimitiveType(type_class, name, 'sal_Int16')
|
|
+ elif type_class == TypeClass.UNSIGNED_SHORT:
|
|
+ uno_type = PrimitiveType(type_class, name, 'sal_uInt16')
|
|
+ elif type_class == TypeClass.LONG:
|
|
+ uno_type = PrimitiveType(type_class, name, 'sal_Int32')
|
|
+ elif type_class == TypeClass.UNSIGNED_LONG:
|
|
+ uno_type = PrimitiveType(type_class, name, 'sal_uInt32')
|
|
+ elif type_class == TypeClass.HYPER:
|
|
+ uno_type = PrimitiveType(type_class, name, 'sal_Int64')
|
|
+ elif type_class == TypeClass.UNSIGNED_HYPER:
|
|
+ uno_type = PrimitiveType(type_class, name, 'sal_uInt64')
|
|
+ elif type_class == TypeClass.FLOAT:
|
|
+ uno_type = PrimitiveType(type_class, name, 'float')
|
|
+ elif type_class == TypeClass.DOUBLE:
|
|
+ uno_type = PrimitiveType(type_class, name, 'double')
|
|
+ elif type_class == TypeClass.STRING:
|
|
+ uno_type = PrimitiveType(type_class, name, 'rtl::OUString')
|
|
+ elif type_class == TypeClass.TYPE:
|
|
+ uno_type = PrimitiveType(type_class, name, 'com::sun::star::uno::Type')
|
|
+ elif type_class == TypeClass.ANY:
|
|
+ uno_type = PrimitiveType(type_class, name, 'com::sun::star::uno::Any')
|
|
+ elif type_class == TypeClass.ENUM:
|
|
+ uno_type = EnumType(val, full_val)
|
|
+ elif type_class == TypeClass.TYPEDEF:
|
|
+ pass
|
|
+ elif type_class == TypeClass.STRUCT:
|
|
+ uno_type = StructType(val, full_val)
|
|
+ elif type_class == TypeClass.UNION:
|
|
+ raise UnsupportedType('union')
|
|
+ elif type_class == TypeClass.EXCEPTION:
|
|
+ uno_type = CompoundType(val, full_val)
|
|
+ elif type_class == TypeClass.SEQUENCE:
|
|
+ uno_type = IndirectType(val, full_val)
|
|
+ elif type_class == TypeClass.ARRAY:
|
|
+ raise UnsupportedType('array')
|
|
+ elif type_class == TypeClass.INTERFACE:
|
|
+ uno_type = InterfaceType(val, full_val)
|
|
+ elif type_class == TypeClass.SERVICE:
|
|
+ raise UnsupportedType('service')
|
|
+ elif type_class == TypeClass.MODULE:
|
|
+ raise UnsupportedType('module')
|
|
+ elif type_class == TypeClass.INTERFACE_METHOD:
|
|
+ uno_type = InterfaceMethodType(val, full_val)
|
|
+ elif type_class == TypeClass.INTERFACE_ATTRIBUTE:
|
|
+ uno_type = InterfaceAttributeType(val, full_val)
|
|
+ elif type_class == TypeClass.UNKNOWN:
|
|
+ raise UnknownType(type)
|
|
+ elif type_class == TypeClass.PROPERTY:
|
|
+ pass
|
|
+ elif type_class == TypeClass.CONSTANT:
|
|
+ pass
|
|
+ elif type_class == TypeClass.CONSTANTS:
|
|
+ pass
|
|
+ elif type_class == TypeClass.SINGLETON:
|
|
+ pass
|
|
+ else:
|
|
+ raise UnknownType(type)
|
|
+
|
|
+ assert uno_type
|
|
+ return uno_type
|
|
+
|
|
+def uno_cast(type, val):
|
|
+ '''Casts val or pointer to UNO type represented by type'''
|
|
+ if val.type.code == gdb.TYPE_CODE_PTR:
|
|
+ return val.cast(type.type().pointer())
|
|
+ else:
|
|
+ return val.cast(type.type())
|
|
+
|
|
+class VoidType(Type):
|
|
+
|
|
+ def __init__(self):
|
|
+ super(VoidType, self).__init__(TypeClass.VOID, "void")
|
|
+ self.typename = "void"
|
|
+
|
|
+class PrimitiveType(Type):
|
|
+
|
|
+ def __init__(self, typeclass, typename_uno, typename_cpp):
|
|
+ super(PrimitiveType, self).__init__(typeclass, typename_uno)
|
|
+ self.typename = str(typename_cpp)
|
|
+
|
|
+class CompoundType(Type):
|
|
+
|
|
+ def __init__(self, type, full_type):
|
|
+ super(CompoundType, self).__init__(type['eTypeClass'], type['pTypeName'].dereference())
|
|
+ self.typename = self.uno2cpp(self.tag)
|
|
+ self._type = full_type
|
|
+
|
|
+ class _iterator(object):
|
|
+
|
|
+ def __init__(self, count, types, names):
|
|
+ self.count = count
|
|
+ self.members = members
|
|
+ self.names = names
|
|
+ self.pos = 0
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self
|
|
+
|
|
+ def next(self):
|
|
+ assert self.pos >= 0 and self.pos <= self.count
|
|
+ if self.pos == self.count:
|
|
+ raise StopIteration
|
|
+
|
|
+ pmember = self.members[self.pos]
|
|
+ assert pmember
|
|
+ pname = self.names[self.i]
|
|
+ assert pname
|
|
+ self.pos = self.pos + 1
|
|
+ member = make_uno_type(pmember.dereference())
|
|
+ assert member
|
|
+ name = str(pname.dereference())
|
|
+ return (name, member)
|
|
+
|
|
+ def attributes(self):
|
|
+ return _iterator(self._type['nMembers'], self._type['ppTypeRefs'],
|
|
+ self._type['ppMemberNames'])
|
|
+
|
|
+class StructType(CompoundType):
|
|
+
|
|
+ def __init__(self, type, full_type):
|
|
+ full_type = full_type.cast(gdb.lookup_type('_typelib_StructTypeDescription'))
|
|
+ super(StructType, self).__init__(type, full_type['aBase'])
|
|
+
|
|
+class IndirectType(Type):
|
|
+
|
|
+ def __init__(self, type, full_type):
|
|
+ super(IndirectType, self).__init__(type['eTypeClass'], type['pTypeName'].dereference())
|
|
+ full_type = full_type.cast(gdb.lookup_type('_typelib_IndirectTypeDescription'))
|
|
+ pelem = full_type['pType']
|
|
+ assert pelem
|
|
+ self.element = make_uno_type(pelem.dereference())
|
|
+ assert self.element
|
|
+ self.typename = TemplateType('com::sun::star::uno::Sequence', self.element.typename)
|
|
+
|
|
+class EnumType(Type):
|
|
+
|
|
+ def __init__(self, type, full_type):
|
|
+ super(EnumType, self).__init__(TypeClass.ENUM, type['pTypeName'].dereference())
|
|
+ self.typename = self.uno2cpp(self.tag)
|
|
+ self._type = full_type.cast(gdb.lookup_type('_typelib_EnumTypeDescription'))
|
|
+
|
|
+ class _iterator(object):
|
|
+
|
|
+ def __init__(self, count, values, names):
|
|
+ self.count = count
|
|
+ self.values = values
|
|
+ self.names = names
|
|
+ self.pos = 0
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self
|
|
+
|
|
+ def next(self):
|
|
+ assert self.pos >= 0 and self.pos <= self.count
|
|
+ if self.pos == self.count:
|
|
+ raise StopIteration
|
|
+
|
|
+ pvalue = self.values[self.pos]
|
|
+ assert pvalue
|
|
+ pname = self.names[self.pos]
|
|
+ assert pname
|
|
+ self.pos = self.pos + 1
|
|
+ val = int(pvalue.dereference())
|
|
+ name = str(pname.dereference())
|
|
+ return (name, val)
|
|
+
|
|
+ def values(self):
|
|
+ return _iterator(self._type['nEnumValues'],
|
|
+ self._type['ppEnumNames'], self._type['pEnumValues'])
|
|
+
|
|
+ def default_value(self):
|
|
+ return self._type['nDefaultEnumValue']
|
|
+
|
|
+class InterfaceMemberType(Type):
|
|
+
|
|
+ def __init__(self, type, full_type):
|
|
+ super(InterfaceMemberType, self).__init__(type['eTypeClass'], type['pTypeName'].dereference())
|
|
+ (interface, delim, member) = self.tag.partition('::')
|
|
+ self.typename = self.uno2cpp(interface) + '::*' + member
|
|
+ full_type = full_type.cast(gdb.lookup_type('_typelib_InterfaceMemberTypeDescription'))
|
|
+ self.position = full_type['nPosition']
|
|
+ pname = full_type['pMemberName']
|
|
+ assert pname
|
|
+ self.name = pname.dereference()
|
|
+
|
|
+class InterfaceMethodType(InterfaceMemberType):
|
|
+
|
|
+ def __init__(self, type, full_type):
|
|
+ full_type = full_type.cast(gdb.lookup_type('_typelib_InterfaceMethodTypeDescription'))
|
|
+ super(InterfaceMethodType, self).__init__(type, full_type['aBase'])
|
|
+ pret = full_type['pReturnTypeRef']
|
|
+ assert pret
|
|
+ self.return_type = make_uno_type(pret.dereference())
|
|
+ assert self.return_type
|
|
+ self.oneway = full_type['bOneWay']
|
|
+ self._type = full_type
|
|
+
|
|
+ class _iterator(object):
|
|
+
|
|
+ def __init__(self, count, values):
|
|
+ self.count = count
|
|
+ self.values = values
|
|
+ self.pos = 0
|
|
+ assert values
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self
|
|
+
|
|
+ def next(self):
|
|
+ assert self.pos >= 0 and self.pos <= self.count
|
|
+ if self.pos == self.count:
|
|
+ raise StopIteration
|
|
+
|
|
+ val = self.values[self.pos]
|
|
+ self.pos = self.pos + 1
|
|
+ return val
|
|
+
|
|
+ class parameter(tuple):
|
|
+
|
|
+ def __init__(self, type):
|
|
+ self.__init_tuple(type)
|
|
+ self.input = type['bIn']
|
|
+ self.output = type['bOut']
|
|
+
|
|
+ def _init_tuple(self, type):
|
|
+ pname = self['pName']
|
|
+ assert pname
|
|
+ ptype = self['pTypeRef']
|
|
+ assert ptype
|
|
+ name = str(pname.dereference())
|
|
+ type = make_uno_type(ptype.dereference())
|
|
+ assert type
|
|
+ super(parameter, self).__init__(name, type)
|
|
+
|
|
+ def parameters(self):
|
|
+ for param in _iterator(self._type['nParams'], self._type['pParams']):
|
|
+ yield parameter(param)
|
|
+
|
|
+ def exceptions(self):
|
|
+ def make_exception(self, pex):
|
|
+ assert pex
|
|
+ ex = make_uno_type(pex.dereference())
|
|
+ assert ex
|
|
+ return ex
|
|
+
|
|
+ for ex in _iterator(
|
|
+ self._type['nExceptions'], self._type['ppExceptions']):
|
|
+ yield make_exception(ex)
|
|
+
|
|
+class InterfaceAttributeType(InterfaceMemberType):
|
|
+
|
|
+ def __init__(self, type, full_type):
|
|
+ full_type = full_type.cast(gdb.lookup_type('_typelib_InterfaceAttributeTypeDescription'))
|
|
+ super(InterfaceAttributeType, self).__init__(type, full_type['aBase'])
|
|
+ self.readonly = full_type['bReadOnly']
|
|
+ ptype = full_type['pAttributeTypeRef']
|
|
+ assert ptype
|
|
+ self.type = make_uno_type(ptype.dereference())
|
|
+ assert self.type
|
|
+
|
|
+class MembersNotInitialized(Exception):
|
|
+ '''Represents exception raised when interface type' members haven't
|
|
+ been initialized(i.e. just level 1 initialization has been
|
|
+ performed)'''
|
|
+ pass
|
|
+
|
|
+class InterfaceType(Type):
|
|
+
|
|
+ def __init__(self, type, full_type):
|
|
+ super(InterfaceType, self).__init__(TypeClass.INTERFACE, type['pTypeName'].dereference())
|
|
+ assert int(type['eTypeClass']) == TypeClass.INTERFACE
|
|
+ self.typename = self.uno2cpp(self.tag)
|
|
+ full_type = full_type.cast(gdb.lookup_type('_typelib_InterfaceTypeDescription'))
|
|
+ self.uik = full_type['aUik']
|
|
+ self._type = full_type
|
|
+
|
|
+ class _iterator(object):
|
|
+
|
|
+ def __init__(self, count, values):
|
|
+ assert values
|
|
+ self.count = count
|
|
+ self.values = values
|
|
+ self.pos = 0
|
|
+
|
|
+ def __iter__(self):
|
|
+ return self
|
|
+
|
|
+ def next(self):
|
|
+ assert self.pos >= 0 and self.pos <= self.count
|
|
+ pvalue = self.values[self.pos]
|
|
+ assert pvalue
|
|
+ self.pos = self.pos + 1
|
|
+ uno = make_uno_type(pvalue.dereference())
|
|
+ assert uno
|
|
+ return uno
|
|
+
|
|
+ def members(self):
|
|
+ return __members(self._type['nMembers'], self._type['ppMembers'])
|
|
+
|
|
+ def all_members(self):
|
|
+ return __members(self._type['nAllMembers'], self._type['ppAllMembers'])
|
|
+
|
|
+ def __members(count, values):
|
|
+ if values == 0:
|
|
+ raise MembersNotInitialized
|
|
+ return _iterator(count, values)
|
|
+
|
|
+ def bases(self):
|
|
+ return _iterator(self._type['nBaseTypes'], self._type['ppBaseTypes'])
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
--
|
|
1.7.6
|
|
|
|
From 9c1e67838844b4826c5a47f03aa4b363c127a705 Mon Sep 17 00:00:00 2001
|
|
From: David Tardon <dtardon@redhat.com>
|
|
Date: Tue, 9 Aug 2011 10:35:19 +0200
|
|
Subject: [PATCH 2/2] install gdb pretty printers
|
|
|
|
---
|
|
Makefile.in | 4 ++-
|
|
solenv/bin/install-gdb-printers | 68 +++++++++++++++++++++++++++++++++++++++
|
|
solenv/gdb/autoload.template | 42 ++++++++++++++++++++++++
|
|
3 files changed, 113 insertions(+), 1 deletions(-)
|
|
create mode 100755 solenv/bin/install-gdb-printers
|
|
create mode 100644 solenv/gdb/autoload.template
|
|
|
|
diff --git a/Makefile.in b/Makefile.in
|
|
index 72ef758..6ea879e 100644
|
|
--- a/Makefile.in
|
|
+++ b/Makefile.in
|
|
@@ -30,7 +30,8 @@ install:
|
|
ooinstall "@INSTALLDIR@" && \
|
|
echo "" && \
|
|
echo "Installation finished, you can now execute:" && \
|
|
- echo "@INSTALLDIR@/program/soffice"
|
|
+ echo "@INSTALLDIR@/program/soffice" && \
|
|
+ install-gdb-printers -a "@INSTALLDIR@"
|
|
|
|
distro-pack-install: install
|
|
./bin/distro-install-clean-up
|
|
@@ -46,6 +47,7 @@ dev-install:
|
|
dev-install:
|
|
@. ./*[Ee]nv.[Ss]et.sh && \
|
|
ooinstall -l @abs_builddir@/install && \
|
|
+ install-gdb-printers -a "$$SOLARVER/$$INPATH/installation/opt" -L && \
|
|
echo "" && \
|
|
echo "Developer installation finished, you can now execute:" && \
|
|
echo "@abs_builddir@/install/program/soffice"
|
|
diff --git a/solenv/bin/install-gdb-printers b/solenv/bin/install-gdb-printers
|
|
new file mode 100755
|
|
index 0000000..719c280
|
|
--- /dev/null
|
|
+++ b/solenv/bin/install-gdb-printers
|
|
@@ -0,0 +1,68 @@
|
|
+#!/bin/bash
|
|
+
|
|
+GDBDIR="${SOLARENV}/gdb"
|
|
+
|
|
+die() {
|
|
+ echo "$1" >&2
|
|
+ exit 1
|
|
+}
|
|
+
|
|
+make_autoload() {
|
|
+ local dir="${DESTDIR}${autoloaddir}/$2"
|
|
+ local gdbfile="${dir}/$3-gdb.py"
|
|
+
|
|
+ if ${create}; then
|
|
+ mkdir -p "${dir}" || die "cannot create dir '${dir}'"
|
|
+ elif ${follow}; then
|
|
+ gdbfile="$(readlink -f "${dir}/$3")-gdb.py"
|
|
+ fi
|
|
+ sed -e "s!%PYTHONDIR%!${pythondir}!" -e "s!%MODULE%!libreoffice.$1!" \
|
|
+ "${GDBDIR}/autoload.template" > "${gdbfile}"
|
|
+}
|
|
+
|
|
+# dir where the autoloaders will be placed
|
|
+autoloaddir=
|
|
+# dir where the pretty printers will be placed
|
|
+pythondir="${GDBDIR}"
|
|
+# Create autoload dir if it does not exist. This only makes sense when
|
|
+# installing into system gdb dir, so $autoloaddir must be absolute path.
|
|
+create=false
|
|
+# Follow links when looking up the path for the autoload file. This only
|
|
+# makes sense for dev-install.
|
|
+follow=false
|
|
+
|
|
+# b defghijklmno qrstuvwxyzABCDEFGHIJK MNOPQRSTUVWXYZ0123456789
|
|
+while getopts :a:cp:L opt; do
|
|
+ case ${opt} in
|
|
+ a) autoloaddir="${OPTARG}" ;;
|
|
+ c) create=true ;;
|
|
+ p) pythondir="${OPTARG}" ;;
|
|
+ L) follow=true ;;
|
|
+ *) die "unknown option ${OPTARG}" ;;
|
|
+ esac
|
|
+done
|
|
+
|
|
+${create} && ${follow} && die "-c and -L cannot be used together"
|
|
+if [[ -n ${DESTDIR} ]]; then
|
|
+ [[ ${autoloaddir:0:1} = / ]] || die 'the arg to -a must be an absolute path'
|
|
+ [[ ${pythondir:0:1} = / ]] || die 'the arg to -p must be an absolute path'
|
|
+fi
|
|
+if ${create}; then
|
|
+ [[ ${autoloaddir:0:1} = / ]] || die 'the arg to -a must be an absolute path'
|
|
+else
|
|
+ [[ ! -d ${DESTDIR}${autoloaddir} ]] && die "directory '${DESTDIR}${autoloaddir}' does not exist"
|
|
+fi
|
|
+[[ ! -d ${GDBDIR} ]] && die "directory '${GDBDIR}' does not exist"
|
|
+
|
|
+if [[ ${DESTDIR}${pythondir} != ${GDBDIR} ]]; then
|
|
+ mkdir -p "${DESTDIR}${pythondir}" || die "cannot create dir '${DESTDIR}${pythondir}'"
|
|
+ cp -r "${GDBDIR}/libreoffice" "${DESTDIR}${pythondir}"
|
|
+fi
|
|
+
|
|
+make_autoload cppu basis-link/ure-link/lib libuno_cppu.so.3
|
|
+make_autoload sal basis-link/ure-link/lib libuno_sal.so.3
|
|
+make_autoload svl basis-link/program libsvllo.so
|
|
+make_autoload sw basis-link/program libswlo.so
|
|
+make_autoload tl basis-link/program libtllo.so
|
|
+
|
|
+# vim:set shiftwidth=4 softtabstop=4 expandtab:
|
|
diff --git a/solenv/gdb/autoload.template b/solenv/gdb/autoload.template
|
|
new file mode 100644
|
|
index 0000000..3351606
|
|
--- /dev/null
|
|
+++ b/solenv/gdb/autoload.template
|
|
@@ -0,0 +1,42 @@
|
|
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
|
|
+#
|
|
+# The contents of this file are subject to the Mozilla Public License Version
|
|
+# 1.1 (the "License"); you may not use this file except in compliance with
|
|
+# the License or as specified alternatively below. You may obtain a copy of
|
|
+# the License at http://www.mozilla.org/MPL/
|
|
+#
|
|
+# Software distributed under the License is distributed on an "AS IS" basis,
|
|
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
+# for the specific language governing rights and limitations under the
|
|
+# License.
|
|
+#
|
|
+# The Initial Developer of the Original Code is
|
|
+# David Tardon, Red Hat Inc. <dtardon@redhat.com>
|
|
+# Portions created by the Initial Developer are Copyright (C) 2010 the
|
|
+# Initial Developer. All Rights Reserved.
|
|
+#
|
|
+# Major Contributor(s):
|
|
+#
|
|
+# For minor contributions see the git repository.
|
|
+#
|
|
+# Alternatively, the contents of this file may be used under the terms of
|
|
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
|
|
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
|
|
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
|
|
+# instead of those above.
|
|
+
|
|
+import os.path
|
|
+import sys
|
|
+
|
|
+import gdb
|
|
+
|
|
+pythondir = os.path.normpath('%PYTHONDIR%')
|
|
+
|
|
+if gdb.current_objfile():
|
|
+ if pythondir not in sys.path:
|
|
+ sys.path.insert(0, pythondir)
|
|
+
|
|
+from %MODULE% import register_pretty_printers
|
|
+register_pretty_printers(gdb.current_objfile())
|
|
+
|
|
+# vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab:
|
|
--
|
|
1.7.6
|
|
|