public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-tromey-python: * python/lib/gdb/libstdcxx/v6/printers.py: New file.
@ 2008-11-22 1:39 tromey
0 siblings, 0 replies; only message in thread
From: tromey @ 2008-11-22 1:39 UTC (permalink / raw)
To: archer-commits
The branch, archer-tromey-python has been updated
via e991a85b6bc0ec175e1d0357f10d74c5dd60780a (commit)
from 6c35e923d5ba223e01f943798d9d093f58acf3da (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit e991a85b6bc0ec175e1d0357f10d74c5dd60780a
Author: Tom Tromey <tromey@redhat.com>
Date: Fri Nov 21 18:38:39 2008 -0700
* python/lib/gdb/libstdcxx/v6/printers.py: New file.
* python/python.c (_initialize_python): Conditionally define
gdb.datadir. Correctly update sys.path. Set gdb.__path__.
* configure: Rebuild.
* configure.ac: Update CONFIG_INSTALL and CONFIG_UNINSTALL for
Python.
* Makefile.in (PY_FILES): New variable.
(install-python): New target.
(uninstall-python): Likewise.
(PY_DIRS): New variable.
-----------------------------------------------------------------------
Summary of changes:
gdb/ChangeLog | 13 +
gdb/Makefile.in | 29 ++
gdb/configure | 2 +
gdb/configure.ac | 2 +
gdb/python/lib/gdb/libstdcxx/v6/printers.py | 522 +++++++++++++++++++++++++++
gdb/python/python.c | 7 +-
6 files changed, 573 insertions(+), 2 deletions(-)
create mode 100644 gdb/python/lib/gdb/libstdcxx/v6/printers.py
First 500 lines of diff:
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index cf899c5..8b15a01 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,18 @@
2008-11-21 Tom Tromey <tromey@redhat.com>
+ * python/lib/gdb/libstdcxx/v6/printers.py: New file.
+ * python/python.c (_initialize_python): Conditionally define
+ gdb.datadir. Correctly update sys.path. Set gdb.__path__.
+ * configure: Rebuild.
+ * configure.ac: Update CONFIG_INSTALL and CONFIG_UNINSTALL for
+ Python.
+ * Makefile.in (PY_FILES): New variable.
+ (install-python): New target.
+ (uninstall-python): Likewise.
+ (PY_DIRS): New variable.
+
+2008-11-21 Tom Tromey <tromey@redhat.com>
+
* python/python.c (get_parameter): Use var_type, not type.
2008-11-21 Tom Tromey <tromey@redhat.com>
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index e60a504..79a9d1c 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1913,6 +1913,35 @@ python-value.o: $(srcdir)/python/python-value.c
$(COMPILE) $(PYTHON_CFLAGS) $(srcdir)/python/python-value.c
$(POSTCOMPILE)
+# All Python install directories. These must be sorted, shallowest
+# first. These are maintained by hand because that is simpler than
+# writing portable sh to make the __init__.py files, and the result is
+# faster.
+PY_DIRS = gdb gdb/libstdcxx gdb/libstdcxx/v6
+
+# All python library files, with the "python/lib" stripped off.
+# Note that we should only install files in the "gdb" module.
+PY_FILES = gdb/libstdcxx/v6/printers.py
+
+# Install the Python library. Python library files go under
+# $(GDB_DATADIR_PATH)/python. We create a dummy __init__.py for
+# each directory, to make importing work properly. If there is a real
+# __init__.py in PY_FILES, it will overwrite the dummy file.
+install-python:
+ dirs='$(PY_DIRS)'; for dir in $$dirs; do \
+ $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR_PATH)/python/$$dir; \
+ if ! test -f $(DESTDIR)$(GDB_DATADIR_PATH)/python/$$dir/__init__.py; then \
+ echo > $(DESTDIR)$(GDB_DATADIR_PATH)/python/$$dir/__init__.py; \
+ fi; \
+ done; \
+ files='$(PY_FILES)'; for file in $$files; do \
+ $(INSTALL_DATA) $(srcdir)/python/lib/$$file $(DESTDIR)$(GDB_DATADIR_PATH)/python/$$file; \
+ done
+
+# Brute force.
+uninstall-python:
+ rm -rf $(DESTDIR)/$(GDB_DATADIR_PATH)/python
+
#
# Dependency tracking. Most of this is conditional on GNU Make being
# found by configure; if GNU Make is not found, we fall back to a
diff --git a/gdb/configure b/gdb/configure
index a3cc179..13ebfae 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -11739,6 +11739,8 @@ _ACEOF
CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_PYTHON_OBS)"
CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_PYTHON_DEPS)"
CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_PYTHON_SRCS)"
+ CONFIG_INSTALL="$CONFIG_INSTALL install-python"
+ CONFIG_UNINSTALL="$CONFIG_UNINSTALL uninstall-python"
ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_PYTHON_CFLAGS)"
# Flags needed to compile Python code (taken from python-config --cflags).
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 77e2f6c..08e0af8 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -681,6 +681,8 @@ if test "${have_libpython}" = yes; then
CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_PYTHON_OBS)"
CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_PYTHON_DEPS)"
CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_PYTHON_SRCS)"
+ CONFIG_INSTALL="$CONFIG_INSTALL install-python"
+ CONFIG_UNINSTALL="$CONFIG_UNINSTALL uninstall-python"
ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_PYTHON_CFLAGS)"
# Flags needed to compile Python code (taken from python-config --cflags).
diff --git a/gdb/python/lib/gdb/libstdcxx/v6/printers.py b/gdb/python/lib/gdb/libstdcxx/v6/printers.py
new file mode 100644
index 0000000..d25b4db
--- /dev/null
+++ b/gdb/python/lib/gdb/libstdcxx/v6/printers.py
@@ -0,0 +1,522 @@
+# Pretty-printers for libstc++.
+
+# Copyright (C) 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import gdb
+import itertools
+
+class StdPointerPrinter:
+ "Print a smart pointer of some kind"
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.val = val
+
+ def to_string (self):
+ return '%s (count %d) %s' % (self.typename, self.val['_M_refcount'],
+ self.val['_M_ptr'])
+
+class UniquePointerPrinter:
+ "Print a unique_ptr"
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ return self.val['_M_t']
+
+class StdListPrinter:
+ "Print a std::list"
+
+ class _iterator:
+ def __init__(self, nodetype, head):
+ self.nodetype = nodetype
+ self.base = head['_M_next']
+ self.head = head.address()
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.base == self.head:
+ raise StopIteration
+ elt = self.base.cast(self.nodetype).dereference()
+ self.base = elt['_M_next']
+ count = self.count
+ self.count = self.count + 1
+ return ('[%d]' % count, elt['_M_data'])
+
+ def __init__(self, val):
+ self.val = val
+
+ def children(self):
+ itype = self.val.type().template_argument(0)
+ nodetype = gdb.Type('std::_List_node<%s>' % itype).pointer()
+ return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
+
+ def to_string(self):
+ if self.val['_M_impl']['_M_node'].address() == self.val['_M_impl']['_M_node']['_M_next']:
+ return 'empty std::list'
+ return 'std::list'
+
+class StdSlistPrinter:
+ "Print a __gnu_cxx::slist"
+
+ class _iterator:
+ def __init__(self, nodetype, head):
+ self.nodetype = nodetype
+ self.base = head['_M_head']['_M_next']
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.base == 0:
+ raise StopIteration
+ elt = self.base.cast(self.nodetype).dereference()
+ self.base = elt['_M_next']
+ count = self.count
+ self.count = self.count + 1
+ return ('[%d]' % count, elt['_M_data'])
+
+ def __init__(self, val):
+ self.val = val
+
+ def children(self):
+ itype = self.val.type().template_argument(0)
+ nodetype = gdb.Type('__gnu_cxx::_Slist_node<%s>' % itype).pointer()
+ return self._iterator(nodetype, self.val)
+
+ def to_string(self):
+ if self.val['_M_head']['_M_next'] == 0:
+ return 'empty __gnu_cxx::slist'
+ return '__gnu_cxx::slist'
+
+class StdVectorPrinter:
+ "Print a std::vector"
+
+ class _iterator:
+ def __init__ (self, start, finish):
+ self.item = start
+ self.finish = finish
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.item == self.finish:
+ raise StopIteration
+ count = self.count
+ self.count = self.count + 1
+ elt = self.item.dereference()
+ self.item = self.item + 1
+ return ('[%d]' % count, elt)
+
+ def __init__(self, val):
+ self.val = val
+
+ def children(self):
+ return self._iterator(self.val['_M_impl']['_M_start'],
+ self.val['_M_impl']['_M_finish'])
+
+ def to_string(self):
+ start = self.val['_M_impl']['_M_start']
+ finish = self.val['_M_impl']['_M_finish']
+ end = self.val['_M_impl']['_M_end_of_storage']
+ return ('std::vector of length %d, capacity %d'
+ % (int (finish - start), int (end - start)))
+
+ def display_hint(self):
+ return 'whatever'
+
+class StdStackOrQueuePrinter:
+ "Print a std::stack or std::queue"
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.visualizer = gdb.get_default_visualizer(val['c'])
+
+ def children (self):
+ return self.visualizer.children()
+
+ def to_string (self):
+ return '%s wrapping: %s' % (self.typename,
+ self.visualizer.to_string())
+
+class RbtreeIterator:
+ def __init__(self, rbtree):
+ self.size = rbtree['_M_t']['_M_impl']['_M_node_count']
+ self.node = rbtree['_M_t']['_M_impl']['_M_header']['_M_left']
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def __len__(self):
+ return int (self.size)
+
+ def next(self):
+ if self.count == self.size:
+ raise StopIteration
+ result = self.node
+ self.count = self.count + 1
+ if self.count < self.size:
+ # Compute the next node.
+ node = self.node
+ if node.dereference()['_M_right']:
+ node = node.dereference()['_M_right']
+ while node.dereference()['_M_left']:
+ node = node.dereference()['_M_left']
+ else:
+ parent = node.dereference()['_M_parent']
+ while node == parent.dereference()['_M_right']:
+ node = parent
+ parent = parent.dereference()['_M_parent']
+ if node.dereference()['_M_right'] != parent:
+ node = parent
+ self.node = node
+ return result
+
+class StdMapPrinter:
+ "Print a std::map or std::multimap"
+
+ # Turn an RbtreeIterator into a pretty-print iterator.
+ class _iter:
+ def __init__(self, rbiter, type):
+ self.rbiter = rbiter
+ self.count = 0
+ self.type = type
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.count % 2 == 0:
+ n = self.rbiter.next()
+ n = n.cast(self.type).dereference()['_M_value_field']
+ self.pair = n
+ item = n['first']
+ else:
+ item = self.pair['second']
+ result = ('[%d]' % self.count, item)
+ self.count = self.count + 1
+ return result
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.val = val
+ self.iter = RbtreeIterator (val)
+
+ def to_string (self):
+ return '%s with %d elements' % (self.typename, len (self.iter))
+
+ def children (self):
+ keytype = self.val.type().template_argument(0)
+ valuetype = self.val.type().template_argument(1)
+ nodetype = gdb.Type('std::_Rb_tree_node< std::pair< const %s, %s > >' % (keytype, valuetype))
+ nodetype = nodetype.pointer()
+ return self._iter (self.iter, nodetype)
+
+ def display_hint (self):
+ return 'map'
+
+class StdSetPrinter:
+ "Print a std::set or std::multiset"
+
+ # Turn an RbtreeIterator into a pretty-print iterator.
+ class _iter:
+ def __init__(self, rbiter, type):
+ self.rbiter = rbiter
+ self.count = 0
+ self.type = type
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ item = self.rbiter.next()
+ item = item.cast(self.type).dereference()['_M_value_field']
+ # FIXME: this is weird ... what to do?
+ # Maybe a 'set' display hint?
+ result = ('[%d]' % self.count, item)
+ self.count = self.count + 1
+ return result
+
+ def __init__ (self, typename, val):
+ self.typename = typename
+ self.val = val
+ self.iter = RbtreeIterator (val)
+
+ def to_string (self):
+ return '%s with %d elements' % (self.typename, len (self.iter))
+
+ def children (self):
+ keytype = self.val.type().template_argument(0)
+ nodetype = gdb.Type('std::_Rb_tree_node< %s >' % keytype).pointer()
+ return self._iter (self.iter, nodetype)
+
+class StdBitsetPrinter:
+ "Print a std::bitset"
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string (self):
+ # If template_argument handled values, we could print the
+ # size. Or we could use a regexp on the type.
+ return 'std::bitset'
+
+ def children (self):
+ words = self.val['_M_w']
+ wtype = words.type()
+ tsize = wtype.target().sizeof()
+ nwords = wtype.sizeof() / tsize
+ result = []
+ byte = 0
+ while byte < nwords:
+ w = words[byte]
+ bit = 0
+ while w != 0:
+ if (w & 1) != 0:
+ # Another spot where we could use 'set'?
+ result.append(('[%d]' % (byte * tsize * 8 + bit), 1))
+ bit = bit + 1
+ w = w >> 1
+ byte = byte + 1
+ return result
+
+class StdDequePrinter:
+ "Print a std::deque"
+
+ class _iter:
+ def __init__(self, node, start, end, last, buffer_size):
+ self.node = node
+ self.p = start
+ self.end = end
+ self.last = last
+ self.buffer_size = buffer_size
+ self.count = 0
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if self.p == self.last:
+ raise StopIteration
+
+ result = ('[%d]' % self.count, self.p.dereference())
+ self.count = self.count + 1
+
+ # Advance the 'cur' pointer.
+ self.p = self.p + 1
+ if self.p == self.end:
+ # If we got to the end of this bucket, move to the
+ # next bucket.
+ self.node = self.node + 1
+ self.p = self.node[0]
+ self.end = self.p + self.buffer_size
+
+ return result
+
+ def __init__(self, val):
+ self.val = val
+ self.elttype = val.type().template_argument(0)
+ size = self.elttype.sizeof ()
+ if size < 512:
+ self.buffer_size = int (512 / size)
+ else:
+ self.buffer_size = 1
+
+ def to_string(self):
+ start = self.val['_M_impl']['_M_start']
+ end = self.val['_M_impl']['_M_finish']
+
+ delta_n = end['_M_node'] - start['_M_node'] - 1
+ delta_s = start['_M_last'] - start['_M_cur']
+ delta_e = end['_M_cur'] - end['_M_first']
+
+ size = self.buffer_size * delta_n + delta_s + delta_e
+
+ return 'std::deque with %d elements' % long (size)
+
+ def children(self):
+ start = self.val['_M_impl']['_M_start']
+ end = self.val['_M_impl']['_M_finish']
+ return self._iter(start['_M_node'], start['_M_cur'], start['_M_last'],
+ end['_M_cur'], self.buffer_size)
+
+class WideEncoding (gdb.Parameter):
+ """The target wide character set is the encoding used for wchar_t."""
+
+ set_doc = "Set the target wide character set."
+ show_doc = "Show the target wide character set."
+
+ # FIXME: needs a complete method -- but does Parameter support it?
+ def __init__ (self):
+ super (WideEncoding, self).__init__ ("target-wide-charset",
+ gdb.COMMAND_SUPPORT,
+ gdb.PARAM_STRING)
+ # I think this is ok for most glibc locales.
+ self.value = 'UTF-32'
+
+target_wide_charset = WideEncoding()
+
+class StdStringPrinter:
+ "Print a std::basic_string of some kind"
+
+ def __init__(self, encoding, val):
+ self.encoding = encoding
+ self.val = val
+
+ def to_string(self):
+ # Look up the target encoding as late as possible.
+ encoding = self.encoding
+ if encoding is None:
+ encoding = gdb.get_parameter('target-charset')
+ elif isinstance(encoding, WideEncoding):
+ encoding = encoding.value
+ return self.val['_M_dataplus']['_M_p'].string(encoding)
+
+class Tr1HashtableIterator:
+ def __init__ (self, hash):
+ self.count = 0
+ self.n_buckets = hash['_M_bucket_count']
+ if self.n_buckets == 0:
+ self.node = False
+ else:
+ self.bucket = hash['_M_buckets']
+ self.node = self.bucket[0]
+ self.update ()
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-11-22 1:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-11-22 1:39 [SCM] archer-tromey-python: * python/lib/gdb/libstdcxx/v6/printers.py: New file tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).