[Libreoffice-commits] .: 4 commits - Makefile.in solenv/bin solenv/gdb
David Tardon
dtardon at kemper.freedesktop.org
Mon Aug 22 08:35:54 PDT 2011
Makefile.in | 4
solenv/bin/install-gdb-printers | 68 +++
solenv/bin/linkoo | 4
solenv/gdb/autoload.template | 42 ++
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 +++++++++++++++++++++++++++
15 files changed, 1884 insertions(+), 3 deletions(-)
New commits:
commit 096d36c9043aba2966657390a758fdbcb4a06eb7
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 22 09:51:43 2011 +0200
the backslash should be escaped here
diff --git a/solenv/bin/linkoo b/solenv/bin/linkoo
index c2565b6..15dfa08 100755
--- a/solenv/bin/linkoo
+++ b/solenv/bin/linkoo
@@ -78,7 +78,7 @@ my $dllre = '\.so$';
$dllre = '\.dylib$' if ($ENV{OS} eq 'MACOSX');
my %replaceable = (
- $program_dir => "($dllre|\.rdb)",
+ $program_dir => "($dllre|\\.rdb)",
$ure_lib_dir => "($dllre|\\.so\\.3\$)",
$program_dir . '/resource' => '\.res$',
$program_dir . '/classes' => '\.jar$',
commit 3c8f40e039b4d32cced201022050769eb40a3a49
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 22 09:50:58 2011 +0200
link versioned uno libs from solver to install dir
diff --git a/solenv/bin/linkoo b/solenv/bin/linkoo
index 5e06459..c2565b6 100755
--- a/solenv/bin/linkoo
+++ b/solenv/bin/linkoo
@@ -79,7 +79,7 @@ $dllre = '\.dylib$' if ($ENV{OS} eq 'MACOSX');
my %replaceable = (
$program_dir => "($dllre|\.rdb)",
- $ure_lib_dir => "$dllre",
+ $ure_lib_dir => "($dllre|\\.so\\.3\$)",
$program_dir . '/resource' => '\.res$',
$program_dir . '/classes' => '\.jar$',
'basis-link/share/config' => '\.zip$',
commit 22ccd4da8610efe98cef3adabb60c761e625e6cd
Author: David Tardon <dtardon at redhat.com>
Date: Tue Aug 9 10:35:19 2011 +0200
install gdb pretty printers
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:
cd @abs_builddir@ && ln -s $$SOLARVER/$$INPATH/installation/opt/ install && \
echo "" && \
$$SOLARENV/bin/linkoo $$SRC_ROOT/install $$SRC_ROOT && \
+ install-gdb-printers -a "$$SOLARVER/$$INPATH/installation/opt" -L && \
echo && echo "Developer installation finished, you can now execute:" && echo && \
if test `uname -s` = Darwin; then \
echo open install/LibreOffice.app; \
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 at 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:
commit 575cd2219f3299cf7a2f9549cdbfcbbe2c79c51b
Author: David Tardon <dtardon at redhat.com>
Date: Fri Jul 29 13:22:35 2011 +0200
add gdb pretty printers
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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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:
More information about the Libreoffice-commits
mailing list