* [PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers
@ 2023-09-28 17:46 Tom Tromey
2023-09-28 17:46 ` [PATCH 1/7] libstdc++: Show full Python stack on error Tom Tromey
` (6 more replies)
0 siblings, 7 replies; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 17:46 UTC (permalink / raw)
To: gcc-patches; +Cc: libstdc++
GDB 14 will include a gdb.ValuePrinter tag class that can be used by
pretty-printers to signal they will accept any extensions that GDB
happens to make over time.
This series started as an attempt to change the libstdc++ printers to
support this. This just involves renaming a bunch of attributes.
There aren't many interesting GDB API additions yet (and I didn't
implement the new ones in libstdc++ yet anyway), but seeing as these
are the flagship pretty-printers, it seemed worthwhile to do.
I added patch 1 when debugging the changes; then proceeded to fix a
bunch of small issues that were pointed out by flake8.
Tested on x86-64 Fedora 36. Let me know what you think.
Tom
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/7] libstdc++: Show full Python stack on error
2023-09-28 17:46 [PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers Tom Tromey
@ 2023-09-28 17:46 ` Tom Tromey
2023-09-28 18:49 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class Tom Tromey
` (5 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 17:46 UTC (permalink / raw)
To: gcc-patches; +Cc: libstdc++, Tom Tromey
This changes the libstdc++ test suite to arrange for gdb to show the
full Python stack if any sort of Python exception occurs. This makes
debugging the printers a little simpler.
libstdc++-v3/ChangeLog:
* testsuite/lib/gdb-test.exp (gdb-test): Enable Python
stack traces from gdb.
---
libstdc++-v3/testsuite/lib/gdb-test.exp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libstdc++-v3/testsuite/lib/gdb-test.exp b/libstdc++-v3/testsuite/lib/gdb-test.exp
index d8e572ef7b3..af7d970d388 100644
--- a/libstdc++-v3/testsuite/lib/gdb-test.exp
+++ b/libstdc++-v3/testsuite/lib/gdb-test.exp
@@ -141,6 +141,8 @@ proc gdb-test { marker {selector {}} {load_xmethods 0} } {
puts $fd "set auto-load no"
# Now that we've disabled auto-load, it's safe to set the target file
puts $fd "file ./$output_file"
+ # See the full backtrace of any failures.
+ puts $fd "set python print-stack full"
# Load & register *our* copy of the pretty-printers
puts $fd "source $printer_code"
puts $fd "python register_libstdcxx_printers(None)"
--
2.40.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class
2023-09-28 17:46 [PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers Tom Tromey
2023-09-28 17:46 ` [PATCH 1/7] libstdc++: Show full Python stack on error Tom Tromey
@ 2023-09-28 17:46 ` Tom Tromey
2023-09-28 20:26 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 3/7] libstdc++: Remove unused Python imports Tom Tromey
` (4 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 17:46 UTC (permalink / raw)
To: gcc-patches; +Cc: libstdc++, Tom Tromey
GDB 14 will add a new ValuePrinter tag class that will be used to
signal that pretty-printers will agree to the "extension protocol" --
essentially that they will follow some simple namespace rules, so that
GDB can add new methods over time.
A couple new methods have already been added to GDB, to support DAP.
While I haven't implemented these for any libstdc++ printers yet, this
patch makes the basic conversion: printers derive from
gdb.ValuePrinter if it is available, and all "non-standard" (that is,
not specified by GDB) members of the various value-printing classes
are renamed to have a leading underscore.
---
libstdc++-v3/python/libstdcxx/v6/printers.py | 1201 +++++++++---------
1 file changed, 605 insertions(+), 596 deletions(-)
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index d60c8003a63..bbc4375541f 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -97,6 +97,12 @@ try:
except ImportError:
pass
+# Use the base class if available.
+if hasattr(gdb, 'ValuePrinter'):
+ printer_base = gdb.ValuePrinter
+else:
+ printer_base = object
+
# Starting with the type ORIG, search for the member type NAME. This
# handles searching upward through superclasses. This is needed to
# work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
@@ -241,43 +247,43 @@ class SmartPtrIterator(Iterator):
"An iterator for smart pointer types with a single 'child' value"
def __init__(self, val):
- self.val = val
+ self._val = val
def __iter__(self):
return self
def __next__(self):
- if self.val is None:
+ if self._val is None:
raise StopIteration
- self.val, val = None, self.val
+ self._val, val = None, self._val
return ('get()', val)
-class SharedPointerPrinter:
+class SharedPointerPrinter(printer_base):
"Print a shared_ptr, weak_ptr, atomic<shared_ptr>, or atomic<weak_ptr>"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
- self.pointer = val['_M_ptr']
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
+ self._pointer = val['_M_ptr']
def children(self):
- return SmartPtrIterator(self.pointer)
+ return SmartPtrIterator(self._pointer)
# Return the _Sp_counted_base<>* that holds the refcounts.
def _get_refcounts(self):
- if self.typename == 'std::atomic':
+ if self._typename == 'std::atomic':
# A tagged pointer is stored as uintptr_t.
- ptr_val = self.val['_M_refcount']['_M_val']['_M_i']
+ ptr_val = self._val['_M_refcount']['_M_val']['_M_i']
ptr_val = ptr_val - (ptr_val % 2) # clear lock bit
- ptr_type = find_type(self.val['_M_refcount'].type, 'pointer')
+ ptr_type = find_type(self._val['_M_refcount'].type, 'pointer')
return ptr_val.cast(ptr_type)
- return self.val['_M_refcount']['_M_pi']
+ return self._val['_M_refcount']['_M_pi']
def to_string(self):
state = 'empty'
refcounts = self._get_refcounts()
- targ = self.val.type.template_argument(0)
+ targ = self._val.type.template_argument(0)
targ = strip_versioned_namespace(str(targ))
if refcounts != 0:
@@ -288,7 +294,7 @@ class SharedPointerPrinter:
else:
state = 'use count %d, weak count %d' % (
usecount, weakcount - 1)
- return '%s<%s> (%s)' % (self.typename, targ, state)
+ return '%s<%s> (%s)' % (self._typename, targ, state)
def _tuple_impl_get(val):
@@ -347,17 +353,17 @@ def unique_ptr_get(val):
return tuple_get(0, tuple_member)
-class UniquePointerPrinter:
+class UniquePointerPrinter(printer_base):
"Print a unique_ptr"
def __init__(self, typename, val):
- self.val = val
+ self._val = val
def children(self):
- return SmartPtrIterator(unique_ptr_get(self.val))
+ return SmartPtrIterator(unique_ptr_get(self._val))
def to_string(self):
- return ('std::unique_ptr<%s>' % (str(self.val.type.template_argument(0))))
+ return ('std::unique_ptr<%s>' % (str(self._val.type.template_argument(0))))
def get_value_from_aligned_membuf(buf, valtype):
@@ -381,55 +387,56 @@ def get_value_from_list_node(node):
raise ValueError("Unsupported implementation for %s" % str(node.type))
-class StdListPrinter:
+class StdListPrinter(printer_base):
"Print a std::list"
class _iterator(Iterator):
def __init__(self, nodetype, head):
- self.nodetype = nodetype
- self.base = head['_M_next']
- self.head = head.address
- self.count = 0
+ 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:
+ 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
+ elt = self._base.cast(self._nodetype).dereference()
+ self._base = elt['_M_next']
+ count = self._count
+ self._count = self._count + 1
val = get_value_from_list_node(elt)
return ('[%d]' % count, val)
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def children(self):
- nodetype = lookup_node_type('_List_node', self.val.type).pointer()
- return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
+ nodetype = lookup_node_type('_List_node', self._val.type).pointer()
+ return self._iterator(nodetype, self._val['_M_impl']['_M_node'])
def to_string(self):
- headnode = self.val['_M_impl']['_M_node']
+ headnode = self._val['_M_impl']['_M_node']
if headnode['_M_next'] == headnode.address:
- return 'empty %s' % (self.typename)
- return '%s' % (self.typename)
+ return 'empty %s' % (self._typename)
+ return '%s' % (self._typename)
-class NodeIteratorPrinter:
+class NodeIteratorPrinter(printer_base):
def __init__(self, typename, val, contname, nodename):
- self.val = val
- self.typename = typename
- self.contname = contname
- self.nodetype = lookup_node_type(nodename, val.type)
+ self._val = val
+ self._typename = typename
+ self._contname = contname
+ self._nodetype = lookup_node_type(nodename, val.type)
def to_string(self):
- if not self.val['_M_node']:
- return 'non-dereferenceable iterator for std::%s' % (self.contname)
- node = self.val['_M_node'].cast(self.nodetype.pointer()).dereference()
+ if not self._val['_M_node']:
+ return 'non-dereferenceable iterator for std::%s' % (self._contname)
+ node = self._val['_M_node'].cast(
+ self._nodetype.pointer()).dereference()
return str(get_value_from_list_node(node))
@@ -448,163 +455,164 @@ class StdFwdListIteratorPrinter(NodeIteratorPrinter):
'_Fwd_list_node')
-class StdSlistPrinter:
+class StdSlistPrinter(printer_base):
"Print a __gnu_cxx::slist"
class _iterator(Iterator):
def __init__(self, nodetype, head):
- self.nodetype = nodetype
- self.base = head['_M_head']['_M_next']
- self.count = 0
+ 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:
+ 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
+ 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, typename, val):
- self.val = val
+ self._val = val
def children(self):
- nodetype = lookup_node_type('__gnu_cxx::_Slist_node', self.val.type)
- return self._iterator(nodetype.pointer(), self.val)
+ nodetype = lookup_node_type('__gnu_cxx::_Slist_node', self._val.type)
+ return self._iterator(nodetype.pointer(), self._val)
def to_string(self):
- if self.val['_M_head']['_M_next'] == 0:
+ if self._val['_M_head']['_M_next'] == 0:
return 'empty __gnu_cxx::slist'
return '__gnu_cxx::slist'
-class StdSlistIteratorPrinter:
+class StdSlistIteratorPrinter(printer_base):
"Print __gnu_cxx::slist::iterator"
def __init__(self, typename, val):
- self.val = val
+ self._val = val
def to_string(self):
- if not self.val['_M_node']:
+ if not self._val['_M_node']:
return 'non-dereferenceable iterator for __gnu_cxx::slist'
nodetype = lookup_node_type(
- '__gnu_cxx::_Slist_node', self.val.type).pointer()
- return str(self.val['_M_node'].cast(nodetype).dereference()['_M_data'])
+ '__gnu_cxx::_Slist_node', self._val.type).pointer()
+ return str(self._val['_M_node'].cast(nodetype).dereference()['_M_data'])
-class StdVectorPrinter:
+class StdVectorPrinter(printer_base):
"Print a std::vector"
class _iterator(Iterator):
def __init__(self, start, finish, bitvec):
- self.bitvec = bitvec
+ self._bitvec = bitvec
if bitvec:
- self.item = start['_M_p']
- self.so = 0
- self.finish = finish['_M_p']
- self.fo = finish['_M_offset']
- itype = self.item.dereference().type
- self.isize = 8 * itype.sizeof
+ self._item = start['_M_p']
+ self._so = 0
+ self._finish = finish['_M_p']
+ self._fo = finish['_M_offset']
+ itype = self._item.dereference().type
+ self._isize = 8 * itype.sizeof
else:
- self.item = start
- self.finish = finish
- self.count = 0
+ self._item = start
+ self._finish = finish
+ self._count = 0
def __iter__(self):
return self
def __next__(self):
- count = self.count
- self.count = self.count + 1
- if self.bitvec:
- if self.item == self.finish and self.so >= self.fo:
+ count = self._count
+ self._count = self._count + 1
+ if self._bitvec:
+ if self._item == self._finish and self._so >= self._fo:
raise StopIteration
- elt = bool(self.item.dereference() & (1 << self.so))
- self.so = self.so + 1
- if self.so >= self.isize:
- self.item = self.item + 1
- self.so = 0
+ elt = bool(self._item.dereference() & (1 << self._so))
+ self._so = self._so + 1
+ if self._so >= self._isize:
+ self._item = self._item + 1
+ self._so = 0
return ('[%d]' % count, elt)
else:
- if self.item == self.finish:
+ if self._item == self._finish:
raise StopIteration
- elt = self.item.dereference()
- self.item = self.item + 1
+ elt = self._item.dereference()
+ self._item = self._item + 1
return ('[%d]' % count, elt)
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
- self.is_bool = val.type.template_argument(0).code == gdb.TYPE_CODE_BOOL
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
+ self._is_bool = val.type.template_argument(
+ 0).code == gdb.TYPE_CODE_BOOL
def children(self):
- return self._iterator(self.val['_M_impl']['_M_start'],
- self.val['_M_impl']['_M_finish'],
- self.is_bool)
+ return self._iterator(self._val['_M_impl']['_M_start'],
+ self._val['_M_impl']['_M_finish'],
+ self._is_bool)
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']
- if self.is_bool:
- start = self.val['_M_impl']['_M_start']['_M_p']
- finish = self.val['_M_impl']['_M_finish']['_M_p']
- fo = self.val['_M_impl']['_M_finish']['_M_offset']
+ start = self._val['_M_impl']['_M_start']
+ finish = self._val['_M_impl']['_M_finish']
+ end = self._val['_M_impl']['_M_end_of_storage']
+ if self._is_bool:
+ start = self._val['_M_impl']['_M_start']['_M_p']
+ finish = self._val['_M_impl']['_M_finish']['_M_p']
+ fo = self._val['_M_impl']['_M_finish']['_M_offset']
itype = start.dereference().type
bl = 8 * itype.sizeof
length = bl * (finish - start) + fo
capacity = bl * (end - start)
return ('%s<bool> of length %d, capacity %d'
- % (self.typename, int(length), int(capacity)))
+ % (self._typename, int(length), int(capacity)))
else:
return ('%s of length %d, capacity %d'
- % (self.typename, int(finish - start), int(end - start)))
+ % (self._typename, int(finish - start), int(end - start)))
def display_hint(self):
return 'array'
-class StdVectorIteratorPrinter:
+class StdVectorIteratorPrinter(printer_base):
"Print std::vector::iterator"
def __init__(self, typename, val):
- self.val = val
+ self._val = val
def to_string(self):
- if not self.val['_M_current']:
+ if not self._val['_M_current']:
return 'non-dereferenceable iterator for std::vector'
- return str(self.val['_M_current'].dereference())
+ return str(self._val['_M_current'].dereference())
-class StdBitIteratorPrinter:
+class StdBitIteratorPrinter(printer_base):
"Print std::vector<bool>'s _Bit_iterator and _Bit_const_iterator"
def __init__(self, typename, val):
- self.val = val
+ self._val = val
def to_string(self):
- if not self.val['_M_p']:
+ if not self._val['_M_p']:
return 'non-dereferenceable iterator for std::vector<bool>'
- return bool(self.val['_M_p'].dereference() & (1 << self.val['_M_offset']))
+ return bool(self._val['_M_p'].dereference() & (1 << self._val['_M_offset']))
-class StdBitReferencePrinter:
+class StdBitReferencePrinter(printer_base):
"Print std::vector<bool>::reference"
def __init__(self, typename, val):
- self.val = val
+ self._val = val
def to_string(self):
- if not self.val['_M_p']:
+ if not self._val['_M_p']:
return 'invalid std::vector<bool>::reference'
- return bool(self.val['_M_p'].dereference() & (self.val['_M_mask']))
+ return bool(self._val['_M_p'].dereference() & (self._val['_M_mask']))
-class StdTuplePrinter:
+class StdTuplePrinter(printer_base):
"Print a std::tuple"
class _iterator(Iterator):
@@ -621,25 +629,25 @@ class StdTuplePrinter:
"Top of tuple tree does not consist of a single node.")
def __init__(self, head):
- self.head = head
+ self._head = head
# Set the base class as the initial head of the
# tuple.
- nodes = self.head.type.fields()
+ nodes = self._head.type.fields()
if self._is_nonempty_tuple(nodes):
# Set the actual head to the first pair.
- self.head = self.head.cast(nodes[0].type)
- self.count = 0
+ self._head = self._head.cast(nodes[0].type)
+ self._count = 0
def __iter__(self):
return self
def __next__(self):
# Check for further recursions in the inheritance tree.
- # For a GCC 5+ tuple self.head is None after visiting all nodes:
- if not self.head:
+ # For a GCC 5+ tuple self._head is None after visiting all nodes:
+ if not self._head:
raise StopIteration
- nodes = self.head.type.fields()
+ nodes = self._head.type.fields()
# For a GCC 4.x tuple there is a final node with no fields:
if len(nodes) == 0:
raise StopIteration
@@ -650,8 +658,8 @@ class StdTuplePrinter:
if len(nodes) == 1:
# This is the last node of a GCC 5+ std::tuple.
- impl = self.head.cast(nodes[0].type)
- self.head = None
+ impl = self._head.cast(nodes[0].type)
+ self._head = None
else:
# Either a node before the last node, or the last node of
# a GCC 4.x tuple (which has an empty parent).
@@ -660,52 +668,52 @@ class StdTuplePrinter:
# - Right node is the actual class contained in the tuple.
# Process right node.
- impl = self.head.cast(nodes[1].type)
+ impl = self._head.cast(nodes[1].type)
# Process left node and set it as head.
- self.head = self.head.cast(nodes[0].type)
+ self._head = self._head.cast(nodes[0].type)
- self.count = self.count + 1
+ self._count = self._count + 1
# Finally, check the implementation. If it is
# wrapped in _M_head_impl return that, otherwise return
# the value "as is".
fields = impl.type.fields()
if len(fields) < 1 or fields[0].name != "_M_head_impl":
- return ('[%d]' % (self.count - 1), impl)
+ return ('[%d]' % (self._count - 1), impl)
else:
- return ('[%d]' % (self.count - 1), impl['_M_head_impl'])
+ return ('[%d]' % (self._count - 1), impl['_M_head_impl'])
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def children(self):
- return self._iterator(self.val)
+ return self._iterator(self._val)
def to_string(self):
- if len(self.val.type.fields()) == 0:
- return 'empty %s' % (self.typename)
- return '%s containing' % (self.typename)
+ if len(self._val.type.fields()) == 0:
+ return 'empty %s' % (self._typename)
+ return '%s containing' % (self._typename)
-class StdStackOrQueuePrinter:
+class StdStackOrQueuePrinter(printer_base):
"Print a std::stack or std::queue"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.visualizer = gdb.default_visualizer(val['c'])
+ self._typename = strip_versioned_namespace(typename)
+ self._visualizer = gdb.default_visualizer(val['c'])
def children(self):
- return self.visualizer.children()
+ return self._visualizer.children()
def to_string(self):
- return '%s wrapping: %s' % (self.typename,
- self.visualizer.to_string())
+ return '%s wrapping: %s' % (self._typename,
+ self._visualizer.to_string())
def display_hint(self):
- if hasattr(self.visualizer, 'display_hint'):
- return self.visualizer.display_hint()
+ if hasattr(self._visualizer, 'display_hint'):
+ return self._visualizer.display_hint()
return None
@@ -716,24 +724,24 @@ class RbtreeIterator(Iterator):
"""
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
+ 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)
+ return int(self._size)
def __next__(self):
- if self.count == self.size:
+ if self._count == self._size:
raise StopIteration
- result = self.node
- self.count = self.count + 1
- if self.count < self.size:
+ result = self._node
+ self._count = self._count + 1
+ if self._count < self._size:
# Compute the next node.
- node = self.node
+ node = self._node
if node.dereference()['_M_right']:
node = node.dereference()['_M_right']
while node.dereference()['_M_left']:
@@ -745,7 +753,7 @@ class RbtreeIterator(Iterator):
parent = parent.dereference()['_M_parent']
if node.dereference()['_M_right'] != parent:
node = parent
- self.node = node
+ self._node = node
return result
@@ -769,38 +777,38 @@ def get_value_from_Rb_tree_node(node):
# class above.
-class StdRbtreeIteratorPrinter:
+class StdRbtreeIteratorPrinter(printer_base):
"Print std::map::iterator, std::set::iterator, etc."
def __init__(self, typename, val):
- self.val = val
- nodetype = lookup_node_type('_Rb_tree_node', self.val.type)
- self.link_type = nodetype.pointer()
+ self._val = val
+ nodetype = lookup_node_type('_Rb_tree_node', self._val.type)
+ self._link_type = nodetype.pointer()
def to_string(self):
- if not self.val['_M_node']:
+ if not self._val['_M_node']:
return 'non-dereferenceable iterator for associative container'
- node = self.val['_M_node'].cast(self.link_type).dereference()
+ node = self._val['_M_node'].cast(self._link_type).dereference()
return str(get_value_from_Rb_tree_node(node))
-class StdDebugIteratorPrinter:
+class StdDebugIteratorPrinter(printer_base):
"Print a debug enabled version of an iterator"
def __init__(self, typename, val):
- self.val = val
+ self._val = val
# Just strip away the encapsulating __gnu_debug::_Safe_iterator
# and return the wrapped iterator value.
def to_string(self):
base_type = gdb.lookup_type('__gnu_debug::_Safe_iterator_base')
- itype = self.val.type.template_argument(0)
- safe_seq = self.val.cast(base_type)['_M_sequence']
+ itype = self._val.type.template_argument(0)
+ safe_seq = self._val.cast(base_type)['_M_sequence']
if not safe_seq:
- return str(self.val.cast(itype))
- if self.val['_M_version'] != safe_seq['_M_version']:
+ return str(self._val.cast(itype))
+ if self._val['_M_version'] != safe_seq['_M_version']:
return "invalid iterator"
- return str(self.val.cast(itype))
+ return str(self._val.cast(itype))
def num_elements(num):
@@ -808,101 +816,101 @@ def num_elements(num):
return '1 element' if num == 1 else '%d elements' % num
-class StdMapPrinter:
+class StdMapPrinter(printer_base):
"Print a std::map or std::multimap"
# Turn an RbtreeIterator into a pretty-print iterator.
class _iter(Iterator):
def __init__(self, rbiter, type):
- self.rbiter = rbiter
- self.count = 0
- self.type = type
+ self._rbiter = rbiter
+ self._count = 0
+ self._type = type
def __iter__(self):
return self
def __next__(self):
- if self.count % 2 == 0:
- n = next(self.rbiter)
- n = n.cast(self.type).dereference()
+ if self._count % 2 == 0:
+ n = next(self._rbiter)
+ n = n.cast(self._type).dereference()
n = get_value_from_Rb_tree_node(n)
- self.pair = n
+ self._pair = n
item = n['first']
else:
- item = self.pair['second']
- result = ('[%d]' % self.count, item)
- self.count = self.count + 1
+ item = self._pair['second']
+ result = ('[%d]' % self._count, item)
+ self._count = self._count + 1
return result
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def to_string(self):
- return '%s with %s' % (self.typename,
- num_elements(len(RbtreeIterator(self.val))))
+ return '%s with %s' % (self._typename,
+ num_elements(len(RbtreeIterator(self._val))))
def children(self):
- node = lookup_node_type('_Rb_tree_node', self.val.type).pointer()
- return self._iter(RbtreeIterator(self.val), node)
+ node = lookup_node_type('_Rb_tree_node', self._val.type).pointer()
+ return self._iter(RbtreeIterator(self._val), node)
def display_hint(self):
return 'map'
-class StdSetPrinter:
+class StdSetPrinter(printer_base):
"Print a std::set or std::multiset"
# Turn an RbtreeIterator into a pretty-print iterator.
class _iter(Iterator):
def __init__(self, rbiter, type):
- self.rbiter = rbiter
- self.count = 0
- self.type = type
+ self._rbiter = rbiter
+ self._count = 0
+ self._type = type
def __iter__(self):
return self
def __next__(self):
- item = next(self.rbiter)
- item = item.cast(self.type).dereference()
+ item = next(self._rbiter)
+ item = item.cast(self._type).dereference()
item = get_value_from_Rb_tree_node(item)
# FIXME: this is weird ... what to do?
# Maybe a 'set' display hint?
- result = ('[%d]' % self.count, item)
- self.count = self.count + 1
+ result = ('[%d]' % self._count, item)
+ self._count = self._count + 1
return result
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def to_string(self):
- return '%s with %s' % (self.typename,
- num_elements(len(RbtreeIterator(self.val))))
+ return '%s with %s' % (self._typename,
+ num_elements(len(RbtreeIterator(self._val))))
def children(self):
- node = lookup_node_type('_Rb_tree_node', self.val.type).pointer()
- return self._iter(RbtreeIterator(self.val), node)
+ node = lookup_node_type('_Rb_tree_node', self._val.type).pointer()
+ return self._iter(RbtreeIterator(self._val), node)
-class StdBitsetPrinter:
+class StdBitsetPrinter(printer_base):
"Print a std::bitset"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ 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 '%s' % (self.typename)
+ return '%s' % (self._typename)
def children(self):
try:
# An empty bitset may not have any members which will
# result in an exception being thrown.
- words = self.val['_M_w']
+ words = self._val['_M_w']
except:
return []
@@ -933,102 +941,102 @@ class StdBitsetPrinter:
return result
-class StdDequePrinter:
+class StdDequePrinter(printer_base):
"Print a std::deque"
class _iter(Iterator):
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
+ 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:
+ if self._p == self._last:
raise StopIteration
- result = ('[%d]' % self.count, self.p.dereference())
- self.count = self.count + 1
+ 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:
+ 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
+ self._node = self._node + 1
+ self._p = self._node[0]
+ self._end = self._p + self._buffer_size
return result
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
- self.elttype = val.type.template_argument(0)
- size = self.elttype.sizeof
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
+ self._elttype = val.type.template_argument(0)
+ size = self._elttype.sizeof
if size < 512:
- self.buffer_size = int(512 / size)
+ self._buffer_size = int(512 / size)
else:
- self.buffer_size = 1
+ self._buffer_size = 1
def to_string(self):
- start = self.val['_M_impl']['_M_start']
- end = self.val['_M_impl']['_M_finish']
+ 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
+ size = self._buffer_size * delta_n + delta_s + delta_e
- return '%s with %s' % (self.typename, num_elements(long(size)))
+ return '%s with %s' % (self._typename, num_elements(long(size)))
def children(self):
- start = self.val['_M_impl']['_M_start']
- end = self.val['_M_impl']['_M_finish']
+ 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)
+ end['_M_cur'], self._buffer_size)
def display_hint(self):
return 'array'
-class StdDequeIteratorPrinter:
+class StdDequeIteratorPrinter(printer_base):
"Print std::deque::iterator"
def __init__(self, typename, val):
- self.val = val
+ self._val = val
def to_string(self):
- if not self.val['_M_cur']:
+ if not self._val['_M_cur']:
return 'non-dereferenceable iterator for std::deque'
- return str(self.val['_M_cur'].dereference())
+ return str(self._val['_M_cur'].dereference())
-class StdStringPrinter:
+class StdStringPrinter(printer_base):
"Print a std::basic_string of some kind"
def __init__(self, typename, val):
- self.val = val
- self.new_string = typename.find("::__cxx11::basic_string") != -1
+ self._val = val
+ self._new_string = typename.find("::__cxx11::basic_string") != -1
def to_string(self):
# Make sure &string works, too.
- type = self.val.type
+ type = self._val.type
if type.code == gdb.TYPE_CODE_REF:
type = type.target()
# Calculate the length of the string so that to_string returns
# the string according to length, not according to first null
# encountered.
- ptr = self.val['_M_dataplus']['_M_p']
- if self.new_string:
- length = self.val['_M_string_length']
+ ptr = self._val['_M_dataplus']['_M_p']
+ if self._new_string:
+ length = self._val['_M_string_length']
# https://sourceware.org/bugzilla/show_bug.cgi?id=17728
ptr = ptr.cast(ptr.type.strip_typedefs())
else:
@@ -1052,173 +1060,173 @@ def access_streambuf_ptrs(streambuf):
return pbase, pptr, egptr
-class StdStringBufPrinter:
+class StdStringBufPrinter(printer_base):
"Print a std::basic_stringbuf"
def __init__(self, _, val):
- self.val = val
+ self._val = val
def to_string(self):
- (pbase, pptr, egptr) = access_streambuf_ptrs(self.val)
+ (pbase, pptr, egptr) = access_streambuf_ptrs(self._val)
# Logic from basic_stringbuf::_M_high_mark()
if pptr:
if not egptr or pptr > egptr:
return pbase.string(length=pptr - pbase)
else:
return pbase.string(length=egptr - pbase)
- return self.val['_M_string']
+ return self._val['_M_string']
def display_hint(self):
return 'string'
-class StdStringStreamPrinter:
+class StdStringStreamPrinter(printer_base):
"Print a std::basic_stringstream"
def __init__(self, typename, val):
- self.val = val
- self.typename = typename
+ self._val = val
+ self._typename = typename
# Check if the stream was redirected:
# This is essentially: val['_M_streambuf'] == val['_M_stringbuf'].address
# However, GDB can't resolve the virtual inheritance, so we do that manually
basetype = [f.type for f in val.type.fields() if f.is_base_class][0]
gdb.set_convenience_variable('__stream', val.cast(basetype).address)
- self.streambuf = gdb.parse_and_eval('$__stream->rdbuf()')
- self.was_redirected = self.streambuf != val['_M_stringbuf'].address
+ self._streambuf = gdb.parse_and_eval('$__stream->rdbuf()')
+ self._was_redirected = self._streambuf != val['_M_stringbuf'].address
def to_string(self):
- if self.was_redirected:
- return "%s redirected to %s" % (self.typename, self.streambuf.dereference())
- return self.val['_M_stringbuf']
+ if self._was_redirected:
+ return "%s redirected to %s" % (self._typename, self._streambuf.dereference())
+ return self._val['_M_stringbuf']
def display_hint(self):
- if self.was_redirected:
+ if self._was_redirected:
return None
return 'string'
class Tr1HashtableIterator(Iterator):
def __init__(self, hashtable):
- self.buckets = hashtable['_M_buckets']
- self.bucket = 0
- self.bucket_count = hashtable['_M_bucket_count']
- self.node_type = find_type(hashtable.type, '_Node').pointer()
- self.node = 0
- while self.bucket != self.bucket_count:
- self.node = self.buckets[self.bucket]
- if self.node:
+ self._buckets = hashtable['_M_buckets']
+ self._bucket = 0
+ self._bucket_count = hashtable['_M_bucket_count']
+ self._node_type = find_type(hashtable.type, '_Node').pointer()
+ self._node = 0
+ while self._bucket != self._bucket_count:
+ self._node = self._buckets[self._bucket]
+ if self._node:
break
- self.bucket = self.bucket + 1
+ self._bucket = self._bucket + 1
def __iter__(self):
return self
def __next__(self):
- if self.node == 0:
+ if self._node == 0:
raise StopIteration
- node = self.node.cast(self.node_type)
+ node = self._node.cast(self._node_type)
result = node.dereference()['_M_v']
- self.node = node.dereference()['_M_next']
- if self.node == 0:
- self.bucket = self.bucket + 1
- while self.bucket != self.bucket_count:
- self.node = self.buckets[self.bucket]
- if self.node:
+ self._node = node.dereference()['_M_next']
+ if self._node == 0:
+ self._bucket = self._bucket + 1
+ while self._bucket != self._bucket_count:
+ self._node = self._buckets[self._bucket]
+ if self._node:
break
- self.bucket = self.bucket + 1
+ self._bucket = self._bucket + 1
return result
class StdHashtableIterator(Iterator):
def __init__(self, hashtable):
- self.node = hashtable['_M_before_begin']['_M_nxt']
+ self._node = hashtable['_M_before_begin']['_M_nxt']
valtype = hashtable.type.template_argument(1)
cached = hashtable.type.template_argument(9).template_argument(0)
node_type = lookup_templ_spec('std::__detail::_Hash_node', str(valtype),
'true' if cached else 'false')
- self.node_type = node_type.pointer()
+ self._node_type = node_type.pointer()
def __iter__(self):
return self
def __next__(self):
- if self.node == 0:
+ if self._node == 0:
raise StopIteration
- elt = self.node.cast(self.node_type).dereference()
- self.node = elt['_M_nxt']
+ elt = self._node.cast(self._node_type).dereference()
+ self._node = elt['_M_nxt']
valptr = elt['_M_storage'].address
valptr = valptr.cast(elt.type.template_argument(0).pointer())
return valptr.dereference()
-class Tr1UnorderedSetPrinter:
+class Tr1UnorderedSetPrinter(printer_base):
"Print a std::unordered_set or tr1::unordered_set"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
- def hashtable(self):
- if self.typename.startswith('std::tr1'):
- return self.val
- return self.val['_M_h']
+ def _hashtable(self):
+ if self._typename.startswith('std::tr1'):
+ return self._val
+ return self._val['_M_h']
def to_string(self):
- count = self.hashtable()['_M_element_count']
- return '%s with %s' % (self.typename, num_elements(count))
+ count = self._hashtable()['_M_element_count']
+ return '%s with %s' % (self._typename, num_elements(count))
@staticmethod
- def format_count(i):
+ def _format_count(i):
return '[%d]' % i
def children(self):
- counter = imap(self.format_count, itertools.count())
- if self.typename.startswith('std::tr1'):
- return izip(counter, Tr1HashtableIterator(self.hashtable()))
- return izip(counter, StdHashtableIterator(self.hashtable()))
+ counter = imap(self._format_count, itertools.count())
+ if self._typename.startswith('std::tr1'):
+ return izip(counter, Tr1HashtableIterator(self._hashtable()))
+ return izip(counter, StdHashtableIterator(self._hashtable()))
-class Tr1UnorderedMapPrinter:
+class Tr1UnorderedMapPrinter(printer_base):
"Print a std::unordered_map or tr1::unordered_map"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
- def hashtable(self):
- if self.typename.startswith('std::tr1'):
- return self.val
- return self.val['_M_h']
+ def _hashtable(self):
+ if self._typename.startswith('std::tr1'):
+ return self._val
+ return self._val['_M_h']
def to_string(self):
- count = self.hashtable()['_M_element_count']
- return '%s with %s' % (self.typename, num_elements(count))
+ count = self._hashtable()['_M_element_count']
+ return '%s with %s' % (self._typename, num_elements(count))
@staticmethod
- def flatten(list):
+ def _flatten(list):
for elt in list:
for i in elt:
yield i
@staticmethod
- def format_one(elt):
+ def _format_one(elt):
return (elt['first'], elt['second'])
@staticmethod
- def format_count(i):
+ def _format_count(i):
return '[%d]' % i
def children(self):
- counter = imap(self.format_count, itertools.count())
+ counter = imap(self._format_count, itertools.count())
# Map over the hash table and flatten the result.
- if self.typename.startswith('std::tr1'):
- data = self.flatten(
- imap(self.format_one, Tr1HashtableIterator(self.hashtable())))
+ if self._typename.startswith('std::tr1'):
+ data = self._flatten(
+ imap(self._format_one, Tr1HashtableIterator(self._hashtable())))
# Zip the two iterators together.
return izip(counter, data)
- data = self.flatten(
- imap(self.format_one, StdHashtableIterator(self.hashtable())))
+ data = self._flatten(
+ imap(self._format_one, StdHashtableIterator(self._hashtable())))
# Zip the two iterators together.
return izip(counter, data)
@@ -1226,50 +1234,50 @@ class Tr1UnorderedMapPrinter:
return 'map'
-class StdForwardListPrinter:
+class StdForwardListPrinter(printer_base):
"Print a std::forward_list"
class _iterator(Iterator):
def __init__(self, nodetype, head):
- self.nodetype = nodetype
- self.base = head['_M_next']
- self.count = 0
+ self._nodetype = nodetype
+ self._base = head['_M_next']
+ self._count = 0
def __iter__(self):
return self
def __next__(self):
- if self.base == 0:
+ 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
+ elt = self._base.cast(self._nodetype).dereference()
+ self._base = elt['_M_next']
+ count = self._count
+ self._count = self._count + 1
valptr = elt['_M_storage'].address
valptr = valptr.cast(elt.type.template_argument(0).pointer())
return ('[%d]' % count, valptr.dereference())
def __init__(self, typename, val):
- self.val = val
- self.typename = strip_versioned_namespace(typename)
+ self._val = val
+ self._typename = strip_versioned_namespace(typename)
def children(self):
- nodetype = lookup_node_type('_Fwd_list_node', self.val.type).pointer()
- return self._iterator(nodetype, self.val['_M_impl']['_M_head'])
+ nodetype = lookup_node_type('_Fwd_list_node', self._val.type).pointer()
+ return self._iterator(nodetype, self._val['_M_impl']['_M_head'])
def to_string(self):
- if self.val['_M_impl']['_M_head']['_M_next'] == 0:
- return 'empty %s' % self.typename
- return '%s' % self.typename
+ if self._val['_M_impl']['_M_head']['_M_next'] == 0:
+ return 'empty %s' % self._typename
+ return '%s' % self._typename
-class SingleObjContainerPrinter(object):
+class SingleObjContainerPrinter(printer_base):
"Base class for printers of containers of single objects"
def __init__(self, val, viz, hint=None):
- self.contained_value = val
- self.visualizer = viz
- self.hint = hint
+ self._contained_value = val
+ self._visualizer = viz
+ self._hint = hint
def _recognize(self, type):
"""Return TYPE as a string after applying type printers"""
@@ -1281,30 +1289,30 @@ class SingleObjContainerPrinter(object):
class _contained(Iterator):
def __init__(self, val):
- self.val = val
+ self._val = val
def __iter__(self):
return self
def __next__(self):
- if self.val is None:
+ if self._val is None:
raise StopIteration
- retval = self.val
- self.val = None
+ retval = self._val
+ self._val = None
return ('[contained value]', retval)
def children(self):
- if self.contained_value is None:
+ if self._contained_value is None:
return self._contained(None)
- if hasattr(self.visualizer, 'children'):
- return self.visualizer.children()
- return self._contained(self.contained_value)
+ if hasattr(self._visualizer, 'children'):
+ return self._visualizer.children()
+ return self._contained(self._contained_value)
def display_hint(self):
# if contained value is a map we want to display in the same way
- if hasattr(self.visualizer, 'children') and hasattr(self.visualizer, 'display_hint'):
- return self.visualizer.display_hint()
- return self.hint
+ if hasattr(self._visualizer, 'children') and hasattr(self._visualizer, 'display_hint'):
+ return self._visualizer.display_hint()
+ return self._hint
def function_pointer_to_name(f):
@@ -1335,24 +1343,24 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
"Print a std::any or std::experimental::any"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.typename = re.sub(
- '^std::experimental::fundamentals_v\d::', 'std::experimental::', self.typename, 1)
- self.val = val
- self.contained_type = None
+ self._typename = strip_versioned_namespace(typename)
+ self._typename = re.sub(
+ '^std::experimental::fundamentals_v\d::', 'std::experimental::', self._typename, 1)
+ self._val = val
+ self._contained_type = None
contained_value = None
visualizer = None
- mgr = self.val['_M_manager']
+ mgr = self._val['_M_manager']
if mgr != 0:
func = function_pointer_to_name(mgr)
if not func:
- raise ValueError(
- "Invalid function pointer in %s" % (self.typename))
+ raise ValueError("Invalid function pointer in %s" %
+ (self._typename))
rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\((enum )?{0}::_Op, (const {0}|{0} const) ?\*, (union )?{0}::_Arg ?\*\)""".format(typename)
m = re.match(rx, func)
if not m:
raise ValueError(
- "Unknown manager function in %s" % self.typename)
+ "Unknown manager function in %s" % self._typename)
mgrname = m.group(1)
# FIXME need to expand 'std::string' so that gdb.lookup_type works
@@ -1388,27 +1396,27 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
mgrtype = mgrtypes[0]
else:
mgrtype = gdb.lookup_type(mgrname)
- self.contained_type = mgrtype.template_argument(0)
+ self._contained_type = mgrtype.template_argument(0)
valptr = None
if '::_Manager_internal' in mgrname:
- valptr = self.val['_M_storage']['_M_buffer'].address
+ valptr = self._val['_M_storage']['_M_buffer'].address
elif '::_Manager_external' in mgrname:
- valptr = self.val['_M_storage']['_M_ptr']
+ valptr = self._val['_M_storage']['_M_ptr']
else:
raise ValueError(
- "Unknown manager function in %s" % self.typename)
+ "Unknown manager function in %s" % self._typename)
contained_value = valptr.cast(
- self.contained_type.pointer()).dereference()
+ self._contained_type.pointer()).dereference()
visualizer = gdb.default_visualizer(contained_value)
super(StdExpAnyPrinter, self).__init__(contained_value, visualizer)
def to_string(self):
- if self.contained_type is None:
- return '%s [no contained value]' % self.typename
- desc = "%s containing " % self.typename
- if hasattr(self.visualizer, 'children'):
- return desc + self.visualizer.to_string()
- valtype = self._recognize(self.contained_type)
+ if self._contained_type is None:
+ return '%s [no contained value]' % self._typename
+ desc = "%s containing " % self._typename
+ if hasattr(self._visualizer, 'children'):
+ return desc + self._visualizer.to_string()
+ valtype = self._recognize(self._contained_type)
return desc + strip_versioned_namespace(str(valtype))
@@ -1418,10 +1426,10 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
def __init__(self, typename, val):
valtype = self._recognize(val.type.template_argument(0))
typename = strip_versioned_namespace(typename)
- self.typename = re.sub(
+ self._typename = re.sub(
'^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3', typename, 1)
payload = val['_M_payload']
- if self.typename.startswith('std::experimental'):
+ if self._typename.startswith('std::experimental'):
engaged = val['_M_engaged']
contained_value = payload
else:
@@ -1439,12 +1447,12 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
contained_value, visualizer)
def to_string(self):
- if self.contained_value is None:
- return "%s [no contained value]" % self.typename
- if hasattr(self.visualizer, 'children'):
- return "%s containing %s" % (self.typename,
- self.visualizer.to_string())
- return self.typename
+ if self._contained_value is None:
+ return "%s [no contained value]" % self._typename
+ if hasattr(self._visualizer, 'children'):
+ return "%s containing %s" % (self._typename,
+ self._visualizer.to_string())
+ return self._typename
class StdVariantPrinter(SingleObjContainerPrinter):
@@ -1452,83 +1460,83 @@ class StdVariantPrinter(SingleObjContainerPrinter):
def __init__(self, typename, val):
alternatives = get_template_arg_list(val.type)
- self.typename = strip_versioned_namespace(typename)
- self.index = val['_M_index']
- if self.index >= len(alternatives):
- self.contained_type = None
+ self._typename = strip_versioned_namespace(typename)
+ self._index = val['_M_index']
+ if self._index >= len(alternatives):
+ self._contained_type = None
contained_value = None
visualizer = None
else:
- self.contained_type = alternatives[int(self.index)]
+ self._contained_type = alternatives[int(self._index)]
addr = val['_M_u']['_M_first']['_M_storage'].address
contained_value = addr.cast(
- self.contained_type.pointer()).dereference()
+ self._contained_type.pointer()).dereference()
visualizer = gdb.default_visualizer(contained_value)
super(StdVariantPrinter, self).__init__(
contained_value, visualizer, 'array')
def to_string(self):
- if self.contained_value is None:
- return "%s [no contained value]" % self.typename
- if hasattr(self.visualizer, 'children'):
- return "%s [index %d] containing %s" % (self.typename, self.index,
- self.visualizer.to_string())
- return "%s [index %d]" % (self.typename, self.index)
+ if self._contained_value is None:
+ return "%s [no contained value]" % self._typename
+ if hasattr(self._visualizer, 'children'):
+ return "%s [index %d] containing %s" % (self._typename, self._index,
+ self._visualizer.to_string())
+ return "%s [index %d]" % (self._typename, self._index)
class StdNodeHandlePrinter(SingleObjContainerPrinter):
"Print a container node handle"
def __init__(self, typename, val):
- self.value_type = val.type.template_argument(1)
+ self._value_type = val.type.template_argument(1)
nodetype = val.type.template_argument(2).template_argument(0)
- self.is_rb_tree_node = is_specialization_of(
+ self._is_rb_tree_node = is_specialization_of(
nodetype.name, '_Rb_tree_node')
- self.is_map_node = val.type.template_argument(0) != self.value_type
+ self._is_map_node = val.type.template_argument(0) != self._value_type
nodeptr = val['_M_ptr']
if nodeptr:
- if self.is_rb_tree_node:
+ if self._is_rb_tree_node:
contained_value = get_value_from_Rb_tree_node(
nodeptr.dereference())
else:
contained_value = get_value_from_aligned_membuf(nodeptr['_M_storage'],
- self.value_type)
+ self._value_type)
visualizer = gdb.default_visualizer(contained_value)
else:
contained_value = None
visualizer = None
optalloc = val['_M_alloc']
- self.alloc = optalloc['_M_payload'] if optalloc['_M_engaged'] else None
+ self._alloc = optalloc['_M_payload'] if optalloc['_M_engaged'] else None
super(StdNodeHandlePrinter, self).__init__(contained_value, visualizer,
'array')
def to_string(self):
desc = 'node handle for '
- if not self.is_rb_tree_node:
+ if not self._is_rb_tree_node:
desc += 'unordered '
- if self.is_map_node:
+ if self._is_map_node:
desc += 'map'
else:
desc += 'set'
- if self.contained_value:
+ if self._contained_value:
desc += ' with element'
- if hasattr(self.visualizer, 'children'):
- return "%s = %s" % (desc, self.visualizer.to_string())
+ if hasattr(self._visualizer, 'children'):
+ return "%s = %s" % (desc, self._visualizer.to_string())
return desc
else:
return 'empty %s' % desc
-class StdExpStringViewPrinter:
+class StdExpStringViewPrinter(printer_base):
"Print a std::basic_string_view or std::experimental::basic_string_view"
def __init__(self, typename, val):
- self.val = val
+ self._val = val
def to_string(self):
- ptr = self.val['_M_str']
- len = self.val['_M_len']
+ ptr = self._val['_M_str']
+ len = self._val['_M_len']
if hasattr(ptr, "lazy_string"):
return ptr.lazy_string(length=len)
return ptr.string(length=len)
@@ -1537,18 +1545,18 @@ class StdExpStringViewPrinter:
return 'string'
-class StdExpPathPrinter:
+class StdExpPathPrinter(printer_base):
"Print a std::experimental::filesystem::path"
def __init__(self, typename, val):
- self.val = val
- self.typename = typename
- start = self.val['_M_cmpts']['_M_impl']['_M_start']
- finish = self.val['_M_cmpts']['_M_impl']['_M_finish']
- self.num_cmpts = int(finish - start)
+ self._val = val
+ self._typename = typename
+ start = self._val['_M_cmpts']['_M_impl']['_M_start']
+ finish = self._val['_M_cmpts']['_M_impl']['_M_finish']
+ self._num_cmpts = int(finish - start)
def _path_type(self):
- t = str(self.val['_M_type'])
+ t = str(self._val['_M_type'])
if t[-9:] == '_Root_dir':
return "root-directory"
if t[-10:] == '_Root_name':
@@ -1556,8 +1564,8 @@ class StdExpPathPrinter:
return None
def to_string(self):
- path = "%s" % self.val['_M_pathname']
- if self.num_cmpts == 0:
+ path = "%s" % self._val['_M_pathname']
+ if self._num_cmpts == 0:
t = self._path_type()
if t:
path = '%s [%s]' % (path, t)
@@ -1565,46 +1573,46 @@ class StdExpPathPrinter:
class _iterator(Iterator):
def __init__(self, cmpts, pathtype):
- self.pathtype = pathtype
- self.item = cmpts['_M_impl']['_M_start']
- self.finish = cmpts['_M_impl']['_M_finish']
- self.count = 0
+ self._pathtype = pathtype
+ self._item = cmpts['_M_impl']['_M_start']
+ self._finish = cmpts['_M_impl']['_M_finish']
+ self._count = 0
def __iter__(self):
return self
def __next__(self):
- if self.item == self.finish:
+ if self._item == self._finish:
raise StopIteration
- item = self.item.dereference()
- count = self.count
- self.count = self.count + 1
- self.item = self.item + 1
+ item = self._item.dereference()
+ count = self._count
+ self._count = self._count + 1
+ self._item = self._item + 1
path = item['_M_pathname']
- t = StdExpPathPrinter(self.pathtype, item)._path_type()
+ t = StdExpPathPrinter(self._pathtype, item)._path_type()
if not t:
t = count
return ('[%s]' % t, path)
def children(self):
- return self._iterator(self.val['_M_cmpts'], self.typename)
+ return self._iterator(self._val['_M_cmpts'], self._typename)
-class StdPathPrinter:
+class StdPathPrinter(printer_base):
"Print a std::filesystem::path"
def __init__(self, typename, val):
- self.val = val
- self.typename = typename
- impl = unique_ptr_get(self.val['_M_cmpts']['_M_impl'])
- self.type = impl.cast(gdb.lookup_type('uintptr_t')) & 3
- if self.type == 0:
- self.impl = impl
+ self._val = val
+ self._typename = typename
+ impl = unique_ptr_get(self._val['_M_cmpts']['_M_impl'])
+ self._type = impl.cast(gdb.lookup_type('uintptr_t')) & 3
+ if self._type == 0:
+ self._impl = impl
else:
- self.impl = None
+ self._impl = None
def _path_type(self):
- t = str(self.type.cast(gdb.lookup_type(self.typename + '::_Type')))
+ t = str(self._type.cast(gdb.lookup_type(self._typename + '::_Type')))
if t[-9:] == '_Root_dir':
return "root-directory"
if t[-10:] == '_Root_name':
@@ -1612,8 +1620,8 @@ class StdPathPrinter:
return None
def to_string(self):
- path = "%s" % self.val['_M_pathname']
- if self.type != 0:
+ path = "%s" % self._val['_M_pathname']
+ if self._type != 0:
t = self._path_type()
if t:
path = '%s [%s]' % (path, t)
@@ -1621,7 +1629,7 @@ class StdPathPrinter:
class _iterator(Iterator):
def __init__(self, impl, pathtype):
- self.pathtype = pathtype
+ self._pathtype = pathtype
if impl:
# We can't access _Impl::_M_size because _Impl is incomplete
# so cast to int* to access the _M_size member at offset zero,
@@ -1630,96 +1638,96 @@ class StdPathPrinter:
char_type = gdb.lookup_type('char')
impl = impl.cast(int_type.pointer())
size = impl.dereference()
- #self.capacity = (impl + 1).dereference()
+ #self._capacity = (impl + 1).dereference()
if hasattr(gdb.Type, 'alignof'):
sizeof_Impl = max(2 * int_type.sizeof, cmpt_type.alignof)
else:
sizeof_Impl = 2 * int_type.sizeof
begin = impl.cast(char_type.pointer()) + sizeof_Impl
- self.item = begin.cast(cmpt_type.pointer())
- self.finish = self.item + size
- self.count = 0
+ self._item = begin.cast(cmpt_type.pointer())
+ self._finish = self._item + size
+ self._count = 0
else:
- self.item = None
- self.finish = None
+ self._item = None
+ self._finish = None
def __iter__(self):
return self
def __next__(self):
- if self.item == self.finish:
+ if self._item == self._finish:
raise StopIteration
- item = self.item.dereference()
- count = self.count
- self.count = self.count + 1
- self.item = self.item + 1
+ item = self._item.dereference()
+ count = self._count
+ self._count = self._count + 1
+ self._item = self._item + 1
path = item['_M_pathname']
- t = StdPathPrinter(self.pathtype, item)._path_type()
+ t = StdPathPrinter(self._pathtype, item)._path_type()
if not t:
t = count
return ('[%s]' % t, path)
def children(self):
- return self._iterator(self.impl, self.typename)
+ return self._iterator(self._impl, self._typename)
-class StdPairPrinter:
+class StdPairPrinter(printer_base):
"Print a std::pair object, with 'first' and 'second' as children"
def __init__(self, typename, val):
- self.val = val
+ self._val = val
class _iter(Iterator):
"An iterator for std::pair types. Returns 'first' then 'second'."
def __init__(self, val):
- self.val = val
- self.which = 'first'
+ self._val = val
+ self._which = 'first'
def __iter__(self):
return self
def __next__(self):
- if self.which is None:
+ if self._which is None:
raise StopIteration
- which = self.which
+ which = self._which
if which == 'first':
- self.which = 'second'
+ self._which = 'second'
else:
- self.which = None
- return (which, self.val[which])
+ self._which = None
+ return (which, self._val[which])
def children(self):
- return self._iter(self.val)
+ return self._iter(self._val)
def to_string(self):
return None
-class StdCmpCatPrinter:
+class StdCmpCatPrinter(printer_base):
"Print a comparison category object"
def __init__(self, typename, val):
- self.typename = typename[typename.rfind(':')+1:]
- self.val = val['_M_value']
+ self._typename = typename[typename.rfind(':')+1:]
+ self._val = val['_M_value']
def to_string(self):
- if self.typename == 'strong_ordering' and self.val == 0:
+ if self._typename == 'strong_ordering' and self._val == 0:
name = 'equal'
else:
names = {2: 'unordered', -1: 'less', 0: 'equivalent', 1: 'greater'}
- name = names[int(self.val)]
- return 'std::{}::{}'.format(self.typename, name)
+ name = names[int(self._val)]
+ return 'std::{}::{}'.format(self._typename, name)
-class StdErrorCodePrinter:
+class StdErrorCodePrinter(printer_base):
"Print a std::error_code or std::error_condition"
_system_is_posix = None # Whether std::system_category() use errno values.
def __init__(self, typename, val):
- self.val = val
- self.typename = strip_versioned_namespace(typename)
+ self._val = val
+ self._typename = strip_versioned_namespace(typename)
# Do this only once ...
if StdErrorCodePrinter._system_is_posix is None:
try:
@@ -1807,14 +1815,14 @@ class StdErrorCodePrinter:
return name.split('::')[-1]
def to_string(self):
- value = self.val['_M_value']
- cat = self.val['_M_cat']
+ value = self._val['_M_value']
+ cat = self._val['_M_cat']
name, alt_name, enum, is_errno = self._category_info(cat)
if value == 0:
default_cats = {'error_code': 'system',
'error_condition': 'generic'}
- if name == default_cats[self._unqualified_name(self.typename)]:
- return self.typename + ' = { }' # default-constructed value
+ if name == default_cats[self._unqualified_name(self._typename)]:
+ return self._typename + ' = { }' # default-constructed value
strval = str(value)
if is_errno and value != 0:
@@ -1829,21 +1837,21 @@ class StdErrorCodePrinter:
name = '"%s"' % name
else:
name = alt_name
- return '%s = {%s: %s}' % (self.typename, name, strval)
+ return '%s = {%s: %s}' % (self._typename, name, strval)
-class StdRegexStatePrinter:
+class StdRegexStatePrinter(printer_base):
"Print a state node in the NFA for a std::regex"
def __init__(self, typename, val):
- self.val = val
- self.typename = typename
+ self._val = val
+ self._typename = typename
def to_string(self):
- opcode = str(self.val['_M_opcode'])
+ opcode = str(self._val['_M_opcode'])
if opcode:
opcode = opcode[25:]
- next_id = self.val['_M_next']
+ next_id = self._val['_M_next']
variants = {'repeat': 'alt', 'alternative': 'alt',
'subexpr_begin': 'subexpr', 'subexpr_end': 'subexpr',
@@ -1856,113 +1864,113 @@ class StdRegexStatePrinter:
v = variants[opcode]
s = "opcode={}, next={}".format(opcode, next_id)
- if v is not None and self.val['_M_' + v] is not None:
- s = "{}, {}={}".format(s, v, self.val['_M_' + v])
+ if v is not None and self._val['_M_' + v] is not None:
+ s = "{}, {}={}".format(s, v, self._val['_M_' + v])
return "{%s}" % (s)
-class StdSpanPrinter:
+class StdSpanPrinter(printer_base):
"Print a std::span"
- class iterator(Iterator):
+ class _iterator(Iterator):
def __init__(self, begin, size):
- self.count = 0
- self.begin = begin
- self.size = size
+ self._count = 0
+ self._begin = begin
+ self._size = size
def __iter__(self):
return self
def __next__(self):
- if self.count == self.size:
+ if self._count == self._size:
raise StopIteration
- count = self.count
- self.count = self.count + 1
- return '[%d]' % count, (self.begin + count).dereference()
+ count = self._count
+ self._count = self._count + 1
+ return '[%d]' % count, (self._begin + count).dereference()
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
if val.type.template_argument(1) == gdb.parse_and_eval('static_cast<std::size_t>(-1)'):
- self.size = val['_M_extent']['_M_extent_value']
+ self._size = val['_M_extent']['_M_extent_value']
else:
- self.size = val.type.template_argument(1)
+ self._size = val.type.template_argument(1)
def to_string(self):
- return '%s of length %d' % (self.typename, self.size)
+ return '%s of length %d' % (self._typename, self._size)
def children(self):
- return self.iterator(self.val['_M_ptr'], self.size)
+ return self._iterator(self._val['_M_ptr'], self._size)
def display_hint(self):
return 'array'
-class StdInitializerListPrinter:
+class StdInitializerListPrinter(printer_base):
"Print a std::initializer_list"
def __init__(self, typename, val):
- self.typename = typename
- self.val = val
- self.size = val['_M_len']
+ self._typename = typename
+ self._val = val
+ self._size = val['_M_len']
def to_string(self):
- return '%s of length %d' % (self.typename, self.size)
+ return '%s of length %d' % (self._typename, self._size)
def children(self):
- return StdSpanPrinter.iterator(self.val['_M_array'], self.size)
+ return StdSpanPrinter._iterator(self._val['_M_array'], self._size)
def display_hint(self):
return 'array'
-class StdAtomicPrinter:
+class StdAtomicPrinter(printer_base):
"Print a std:atomic"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
- self.shptr_printer = None
- self.value_type = self.val.type.template_argument(0)
- if self.value_type.tag is not None:
- typ = strip_versioned_namespace(self.value_type.tag)
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
+ self._shptr_printer = None
+ self._value_type = self._val.type.template_argument(0)
+ if self._value_type.tag is not None:
+ typ = strip_versioned_namespace(self._value_type.tag)
if typ.startswith('std::shared_ptr<') or typ.startswith('std::weak_ptr<'):
impl = val['_M_impl']
- self.shptr_printer = SharedPointerPrinter(typename, impl)
+ self._shptr_printer = SharedPointerPrinter(typename, impl)
self.children = self._shptr_children
def _shptr_children(self):
- return SmartPtrIterator(self.shptr_printer.pointer)
+ return SmartPtrIterator(self._shptr_printer._pointer)
def to_string(self):
- if self.shptr_printer is not None:
- return self.shptr_printer.to_string()
-
- if self.value_type.code == gdb.TYPE_CODE_INT:
- val = self.val['_M_i']
- elif self.value_type.code == gdb.TYPE_CODE_FLT:
- val = self.val['_M_fp']
- elif self.value_type.code == gdb.TYPE_CODE_PTR:
- val = self.val['_M_b']['_M_p']
- elif self.value_type.code == gdb.TYPE_CODE_BOOL:
- val = self.val['_M_base']['_M_i']
+ if self._shptr_printer is not None:
+ return self._shptr_printer.to_string()
+
+ if self._value_type.code == gdb.TYPE_CODE_INT:
+ val = self._val['_M_i']
+ elif self._value_type.code == gdb.TYPE_CODE_FLT:
+ val = self._val['_M_fp']
+ elif self._value_type.code == gdb.TYPE_CODE_PTR:
+ val = self._val['_M_b']['_M_p']
+ elif self._value_type.code == gdb.TYPE_CODE_BOOL:
+ val = self._val['_M_base']['_M_i']
else:
- val = self.val['_M_i']
- return '%s<%s> = { %s }' % (self.typename, str(self.value_type), val)
+ val = self._val['_M_i']
+ return '%s<%s> = { %s }' % (self._typename, str(self._value_type), val)
-class StdFormatArgsPrinter:
+class StdFormatArgsPrinter(printer_base):
"Print a std::basic_format_args"
# TODO: add printer for basic_format_arg<Context> and print out children.
# TODO: add printer for __format::_ArgStore<Context, Args...>.
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def to_string(self):
- targs = get_template_arg_list(self.val.type)
+ targs = get_template_arg_list(self._val.type)
char_type = get_template_arg_list(targs[0])[1]
if char_type == gdb.lookup_type('char'):
typ = 'std::format_args'
@@ -1971,32 +1979,32 @@ class StdFormatArgsPrinter:
else:
typ = 'std::basic_format_args'
- size = self.val['_M_packed_size']
+ size = self._val['_M_packed_size']
if size == 1:
return "%s with 1 argument" % (typ)
if size == 0:
- size = self.val['_M_unpacked_size']
+ size = self._val['_M_unpacked_size']
return "%s with %d arguments" % (typ, size)
def std_ratio_t_tuple(ratio_type):
# TODO use reduced period i.e. duration::period
- period = self.val.type.template_argument(1)
+ period = self._val.type.template_argument(1)
num = period.template_argument(0)
den = period.template_argument(1)
return (num, den)
-class StdChronoDurationPrinter:
+class StdChronoDurationPrinter(printer_base):
"Print a std::chrono::duration"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def _ratio(self):
# TODO use reduced period i.e. duration::period
- period = self.val.type.template_argument(1)
+ period = self._val.type.template_argument(1)
num = period.template_argument(0)
den = period.template_argument(1)
return (num, den)
@@ -2023,21 +2031,21 @@ class StdChronoDurationPrinter:
return "[{}/{}]s".format(num, den)
def to_string(self):
- r = self.val['__r']
+ r = self._val['__r']
if r.type.strip_typedefs().code == gdb.TYPE_CODE_FLT:
r = "%g" % r
return "std::chrono::duration = {{ {}{} }}".format(r, self._suffix())
-class StdChronoTimePointPrinter:
+class StdChronoTimePointPrinter(printer_base):
"Print a std::chrono::time_point"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def _clock(self):
- clock = self.val.type.template_argument(0)
+ clock = self._val.type.template_argument(0)
name = strip_versioned_namespace(clock.name)
if name == 'std::chrono::_V2::system_clock' \
or name == 'std::chrono::system_clock':
@@ -2057,7 +2065,7 @@ class StdChronoTimePointPrinter:
def to_string(self, abbrev=False):
clock, offset = self._clock()
- d = self.val['__d']
+ d = self._val['__d']
r = d['__r']
printer = StdChronoDurationPrinter(d.type.name, d)
suffix = printer._suffix()
@@ -2076,16 +2084,16 @@ class StdChronoTimePointPrinter:
return '%s = { %s }' % (clock, s)
-class StdChronoZonedTimePrinter:
+class StdChronoZonedTimePrinter(printer_base):
"Print a std::chrono::zoned_time"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def to_string(self):
- zone = self.val['_M_zone'].dereference()['_M_name']
- time = self.val['_M_tp']
+ zone = self._val['_M_zone'].dereference()['_M_name']
+ time = self._val['_M_tp']
printer = StdChronoTimePointPrinter(time.type.name, time)
time = printer.to_string(True)
return 'std::chrono::zoned_time = {{ {} {} }}'.format(zone, time)
@@ -2098,16 +2106,16 @@ weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
'Saturday', 'Sunday']
-class StdChronoCalendarPrinter:
+class StdChronoCalendarPrinter(printer_base):
"Print a std::chrono::day, std::chrono::month, std::chrono::year etc."
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def to_string(self):
- val = self.val
- typ = self.typename
+ val = self._val
+ typ = self._typename
if 'month' in typ and typ != 'std::chrono::year_month_day_last':
m = val['_M_m']
if typ.startswith('std::chrono::year'):
@@ -2161,53 +2169,53 @@ class StdChronoCalendarPrinter:
return '{:02}:{:02}:{:02}{}'.format(h, m, s, fract)
-class StdChronoTimeZonePrinter:
+class StdChronoTimeZonePrinter(printer_base):
"Print a chrono::time_zone or chrono::time_zone_link"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def to_string(self):
- str = '%s = %s' % (self.typename, self.val['_M_name'])
- if self.typename.endswith("_link"):
- str += ' -> %s' % (self.val['_M_target'])
+ str = '%s = %s' % (self._typename, self._val['_M_name'])
+ if self._typename.endswith("_link"):
+ str += ' -> %s' % (self._val['_M_target'])
return str
-class StdChronoLeapSecondPrinter:
+class StdChronoLeapSecondPrinter(printer_base):
"Print a chrono::leap_second"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def to_string(self):
- date = self.val['_M_s']['__r']
+ date = self._val['_M_s']['__r']
neg = '+-'[date < 0]
- return '%s %d (%c)' % (self.typename, abs(date), neg)
+ return '%s %d (%c)' % (self._typename, abs(date), neg)
-class StdChronoTzdbPrinter:
+class StdChronoTzdbPrinter(printer_base):
"Print a chrono::tzdb"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def to_string(self):
- return '%s %s' % (self.typename, self.val['version'])
+ return '%s %s' % (self._typename, self._val['version'])
-class StdChronoTimeZoneRulePrinter:
+class StdChronoTimeZoneRulePrinter(printer_base):
"Print a chrono::time_zone rule"
def __init__(self, typename, val):
- self.typename = strip_versioned_namespace(typename)
- self.val = val
+ self._typename = strip_versioned_namespace(typename)
+ self._val = val
def to_string(self):
- on = self.val['on']
+ on = self._val['on']
kind = on['kind']
month = months[on['month']]
suffixes = {1: 'st', 2: 'nd', 3: 'rd',
@@ -2230,24 +2238,24 @@ class StdChronoTimeZoneRulePrinter:
direction[1], month,
ordinal_day)
return 'time_zone rule {} from {} to {} starting on {}'.format(
- self.val['name'], self.val['from'], self.val['to'], start)
+ self._val['name'], self._val['from'], self._val['to'], start)
-class StdLocalePrinter:
+class StdLocalePrinter(printer_base):
"Print a std::locale"
def __init__(self, typename, val):
- self.val = val
- self.typename = typename
+ self._val = val
+ self._typename = typename
def to_string(self):
- names = self.val['_M_impl']['_M_names']
+ names = self._val['_M_impl']['_M_names']
mod = ''
if names[0] == 0:
name = '*'
else:
- cats = gdb.parse_and_eval(self.typename + '::_S_categories')
- ncat = gdb.parse_and_eval(self.typename + '::_S_categories_size')
+ cats = gdb.parse_and_eval(self._typename + '::_S_categories')
+ ncat = gdb.parse_and_eval(self._typename + '::_S_categories_size')
n = names[0].string()
cat = cats[0].string()
name = '{}={}'.format(cat, n)
@@ -2284,7 +2292,7 @@ class RxPrinter(object):
def __init__(self, name, function):
super(RxPrinter, self).__init__()
self.name = name
- self.function = function
+ self._function = function
self.enabled = True
def invoke(self, value):
@@ -2295,7 +2303,7 @@ class RxPrinter(object):
if hasattr(gdb.Value, "referenced_value"):
value = value.referenced_value()
- return self.function(self.name, value)
+ return self._function(self.name, value)
# A pretty-printer that conforms to the "PrettyPrinter" protocol from
# gdb.printing. It can also be used directly as an old-style printer.
@@ -2305,20 +2313,20 @@ class Printer(object):
def __init__(self, name):
super(Printer, self).__init__()
self.name = name
- self.subprinters = []
- self.lookup = {}
+ self._subprinters = []
+ self._lookup = {}
self.enabled = True
- self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$')
+ self._compiled_rx = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$')
def add(self, name, function):
# A small sanity check.
# FIXME
- if not self.compiled_rx.match(name):
+ if not self._compiled_rx.match(name):
raise ValueError(
'libstdc++ programming error: "%s" does not match' % name)
printer = RxPrinter(name, function)
- self.subprinters.append(printer)
- self.lookup[name] = printer
+ self._subprinters.append(printer)
+ self._lookup[name] = printer
# Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
def add_version(self, base, name, function):
@@ -2351,7 +2359,7 @@ class Printer(object):
# All the types we match are template types, so we can use a
# dictionary.
- match = self.compiled_rx.match(typename)
+ match = self._compiled_rx.match(typename)
if not match:
return None
@@ -2361,8 +2369,8 @@ class Printer(object):
if hasattr(gdb.Value, "referenced_value"):
val = val.referenced_value()
- if basename in self.lookup:
- return self.lookup[basename].invoke(val)
+ if basename in self._lookup:
+ return self._lookup[basename].invoke(val)
# Cannot find a pretty printer. Return None.
return None
@@ -2384,7 +2392,7 @@ class TemplateTypePrinter(object):
def __init__(self, name, defargs):
self.name = name
- self.defargs = defargs
+ self._defargs = defargs
self.enabled = True
class _recognizer(object):
@@ -2392,8 +2400,8 @@ class TemplateTypePrinter(object):
def __init__(self, name, defargs):
self.name = name
- self.defargs = defargs
- # self.type_obj = None
+ self._defargs = defargs
+ # self._type_obj = None
def recognize(self, type_obj):
"""
@@ -2416,7 +2424,7 @@ class TemplateTypePrinter(object):
# The actual template argument in the type:
targ = template_args[n]
# The default template argument for the class template:
- defarg = self.defargs.get(n)
+ defarg = self._defargs.get(n)
if defarg is not None:
# Substitute other template arguments into the default:
defarg = defarg.format(*template_args)
@@ -2469,7 +2477,7 @@ class TemplateTypePrinter(object):
def instantiate(self):
"Return a recognizer object for this type printer."
- return self._recognizer(self.name, self.defargs)
+ return self._recognizer(self.name, self._defargs)
def add_one_template_type_printer(obj, name, defargs):
@@ -2533,58 +2541,59 @@ class FilteringTypePrinter(object):
"""
def __init__(self, template, name, targ1=None):
- self.template = template
+ self._template = template
self.name = name
- self.targ1 = targ1
+ self._targ1 = targ1
self.enabled = True
class _recognizer(object):
"The recognizer class for FilteringTypePrinter."
def __init__(self, template, name, targ1):
- self.template = template
+ self._template = template
self.name = name
- self.targ1 = targ1
- self.type_obj = None
+ self._targ1 = targ1
+ self._type_obj = None
def recognize(self, type_obj):
"""
- If type_obj starts with self.template and is the same type as
+ If type_obj starts with self._template and is the same type as
self.name then return self.name, otherwise None.
"""
if type_obj.tag is None:
return None
- if self.type_obj is None:
- if self.targ1 is not None:
- if not type_obj.tag.startswith('{}<{}'.format(self.template, self.targ1)):
+ if self._type_obj is None:
+ if self._targ1 is not None:
+ if not type_obj.tag.startswith('{}<{}'.format(self._template, self._targ1)):
# Filter didn't match.
return None
- elif not type_obj.tag.startswith(self.template):
+ elif not type_obj.tag.startswith(self._template):
# Filter didn't match.
return None
try:
- self.type_obj = gdb.lookup_type(self.name).strip_typedefs()
+ self._type_obj = gdb.lookup_type(
+ self.name).strip_typedefs()
except:
pass
- if self.type_obj is None:
+ if self._type_obj is None:
return None
- if gdb.types.get_basic_type(self.type_obj) == gdb.types.get_basic_type(type_obj):
+ if gdb.types.get_basic_type(self._type_obj) == gdb.types.get_basic_type(type_obj):
return strip_inline_namespaces(self.name)
# Workaround ambiguous typedefs matching both std:: and std::__cxx11:: symbols.
- if self.template.split('::')[-1] == 'basic_string':
- if self.type_obj.tag.replace('__cxx11::', '') == type_obj.tag.replace('__cxx11::', ''):
+ if self._template.split('::')[-1] == 'basic_string':
+ if self._type_obj.tag.replace('__cxx11::', '') == type_obj.tag.replace('__cxx11::', ''):
return strip_inline_namespaces(self.name)
return None
def instantiate(self):
"Return a recognizer object for this type printer."
- return self._recognizer(self.template, self.name, self.targ1)
+ return self._recognizer(self._template, self.name, self._targ1)
def add_one_type_printer(obj, template, name, targ1=None):
--
2.40.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 3/7] libstdc++: Remove unused Python imports
2023-09-28 17:46 [PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers Tom Tromey
2023-09-28 17:46 ` [PATCH 1/7] libstdc++: Show full Python stack on error Tom Tromey
2023-09-28 17:46 ` [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class Tom Tromey
@ 2023-09-28 17:46 ` Tom Tromey
2023-09-28 18:53 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 4/7] libstdc++: Remove unused locals from printers.py Tom Tromey
` (3 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 17:46 UTC (permalink / raw)
To: gcc-patches; +Cc: libstdc++, Tom Tromey
flake8 pointed out some unused imports.
libstdc++-v3/ChangeLog:
* python/libstdcxx/v6/printers.py: Don't import 'os'.
* python/libstdcxx/v6/__init__.py: Don't import 'gdb'.
---
libstdc++-v3/python/libstdcxx/v6/__init__.py | 2 --
libstdc++-v3/python/libstdcxx/v6/printers.py | 1 -
2 files changed, 3 deletions(-)
diff --git a/libstdc++-v3/python/libstdcxx/v6/__init__.py b/libstdc++-v3/python/libstdcxx/v6/__init__.py
index df654acd0c2..8b2cbc60a1b 100644
--- a/libstdc++-v3/python/libstdcxx/v6/__init__.py
+++ b/libstdc++-v3/python/libstdcxx/v6/__init__.py
@@ -13,8 +13,6 @@
# 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
-
# Load the xmethods if GDB supports them.
def gdb_has_xmethods():
try:
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index bbc4375541f..8d44244afb0 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -19,7 +19,6 @@ import gdb
import itertools
import re
import sys
-import os
import errno
import datetime
--
2.40.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 4/7] libstdc++: Remove unused locals from printers.py
2023-09-28 17:46 [PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers Tom Tromey
` (2 preceding siblings ...)
2023-09-28 17:46 ` [PATCH 3/7] libstdc++: Remove unused Python imports Tom Tromey
@ 2023-09-28 17:46 ` Tom Tromey
2023-09-28 18:53 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 5/7] libstdc++: Remove std_ratio_t_tuple Tom Tromey
` (2 subsequent siblings)
6 siblings, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 17:46 UTC (permalink / raw)
To: gcc-patches; +Cc: libstdc++, Tom Tromey
flake8 pointed out some unused local variables in the libstdc++
pretty-printers. This removes them.
libstdc++-v3/ChangeLog:
* python/libstdcxx/v6/printers.py
(StdExpOptionalPrinter.__init__, lookup_node_type):
Remove unused variables.
---
libstdc++-v3/python/libstdcxx/v6/printers.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 8d44244afb0..6bf4fe891fd 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -169,7 +169,7 @@ def lookup_node_type(nodename, containertype):
valtype = valtype.strip_typedefs()
try:
return lookup_templ_spec(nodename, valtype)
- except gdb.error as e:
+ except gdb.error:
# For debug mode containers the node is in std::__cxx1998.
if is_member_of_namespace(nodename, 'std'):
if is_member_of_namespace(containertype, 'std::__cxx1998',
@@ -1423,7 +1423,6 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
"Print a std::optional or std::experimental::optional"
def __init__(self, typename, val):
- valtype = self._recognize(val.type.template_argument(0))
typename = strip_versioned_namespace(typename)
self._typename = re.sub(
'^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3', typename, 1)
--
2.40.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 5/7] libstdc++: Remove std_ratio_t_tuple
2023-09-28 17:46 [PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers Tom Tromey
` (3 preceding siblings ...)
2023-09-28 17:46 ` [PATCH 4/7] libstdc++: Remove unused locals from printers.py Tom Tromey
@ 2023-09-28 17:46 ` Tom Tromey
2023-09-28 19:01 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers Tom Tromey
2023-09-28 17:46 ` [PATCH 7/7] libstdc++: Use Python "not in" operator Tom Tromey
6 siblings, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 17:46 UTC (permalink / raw)
To: gcc-patches; +Cc: libstdc++, Tom Tromey
This removes the std_ratio_t_tuple function from the Python
pretty-printer code. It is not used. Apparently the relevant parts
were moved to StdChronoDurationPrinter._ratio at some point in the
past.
libstdc++-v3/ChangeLog:
* python/libstdcxx/v6/printers.py (std_ratio_t_tuple):
Remove.
---
libstdc++-v3/python/libstdcxx/v6/printers.py | 8 --------
1 file changed, 8 deletions(-)
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 6bf4fe891fd..94ac9232da7 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1985,14 +1985,6 @@ class StdFormatArgsPrinter(printer_base):
return "%s with %d arguments" % (typ, size)
-def std_ratio_t_tuple(ratio_type):
- # TODO use reduced period i.e. duration::period
- period = self._val.type.template_argument(1)
- num = period.template_argument(0)
- den = period.template_argument(1)
- return (num, den)
-
-
class StdChronoDurationPrinter(printer_base):
"Print a std::chrono::duration"
--
2.40.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers
2023-09-28 17:46 [PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers Tom Tromey
` (4 preceding siblings ...)
2023-09-28 17:46 ` [PATCH 5/7] libstdc++: Remove std_ratio_t_tuple Tom Tromey
@ 2023-09-28 17:46 ` Tom Tromey
2023-09-28 18:51 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 7/7] libstdc++: Use Python "not in" operator Tom Tromey
6 siblings, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 17:46 UTC (permalink / raw)
To: gcc-patches; +Cc: libstdc++, Tom Tromey
flake8 pointed out that some regexes in the pretty-printers are
missing a backslash. This patch fixes these.
libstdc++-v3/ChangeLog:
* python/libstdcxx/v6/printers.py
(StdExpAnyPrinter.__init__, StdExpOptionalPrinter.__init__):
Add missing backslash.
* python/libstdcxx/v6/xmethods.py
(ArrayMethodsMatcher.match, DequeMethodsMatcher.match)
(ForwardListMethodsMatcher.match, ListMethodsMatcher.match)
(VectorMethodsMatcher.match)
(AssociativeContainerMethodsMatcher.match)
(UniquePtrGetWorker.__call__, UniquePtrMethodsMatcher.match)
(SharedPtrSubscriptWorker.__call__)
(SharedPtrMethodsMatcher.match): Add missing backslash.
---
libstdc++-v3/python/libstdcxx/v6/printers.py | 6 +++---
libstdc++-v3/python/libstdcxx/v6/xmethods.py | 22 ++++++++++----------
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index 94ac9232da7..d125236b777 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -1344,7 +1344,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
def __init__(self, typename, val):
self._typename = strip_versioned_namespace(typename)
self._typename = re.sub(
- '^std::experimental::fundamentals_v\d::', 'std::experimental::', self._typename, 1)
+ '^std::experimental::fundamentals_v\\d::', 'std::experimental::', self._typename, 1)
self._val = val
self._contained_type = None
contained_value = None
@@ -1377,7 +1377,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
mgrtypes = []
for s in strings:
try:
- x = re.sub("std::string(?!\w)", s, m.group(1))
+ x = re.sub("std::string(?!\\w)", s, m.group(1))
# The following lookup might raise gdb.error if the
# manager function was never instantiated for 's' in the
# program, because there will be no such type.
@@ -1425,7 +1425,7 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
def __init__(self, typename, val):
typename = strip_versioned_namespace(typename)
self._typename = re.sub(
- '^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3', typename, 1)
+ '^std::(experimental::|)(fundamentals_v\\d::|)(.*)', r'std::\1\3', typename, 1)
payload = val['_M_payload']
if self._typename.startswith('std::experimental'):
engaged = val['_M_engaged']
diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
index 025b1b86ed0..eafecbb148e 100644
--- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
+++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
@@ -159,7 +159,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name):
- if not re.match('^std::(__\d+::)?array<.*>$', class_type.tag):
+ if not re.match('^std::(__\\d+::)?array<.*>$', class_type.tag):
return None
method = self._method_dict.get(method_name)
if method is None or not method.enabled:
@@ -284,7 +284,7 @@ class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name):
- if not re.match('^std::(__\d+::)?deque<.*>$', class_type.tag):
+ if not re.match('^std::(__\\d+::)?deque<.*>$', class_type.tag):
return None
method = self._method_dict.get(method_name)
if method is None or not method.enabled:
@@ -332,7 +332,7 @@ class ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name):
- if not re.match('^std::(__\d+::)?forward_list<.*>$', class_type.tag):
+ if not re.match('^std::(__\\d+::)?forward_list<.*>$', class_type.tag):
return None
method = self._method_dict.get(method_name)
if method is None or not method.enabled:
@@ -419,7 +419,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name):
- if not re.match('^std::(__\d+::)?(__cxx11::)?list<.*>$', class_type.tag):
+ if not re.match('^std::(__\\d+::)?(__cxx11::)?list<.*>$', class_type.tag):
return None
method = self._method_dict.get(method_name)
if method is None or not method.enabled:
@@ -542,7 +542,7 @@ class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name):
- if not re.match('^std::(__\d+::)?vector<.*>$', class_type.tag):
+ if not re.match('^std::(__\\d+::)?vector<.*>$', class_type.tag):
return None
method = self._method_dict.get(method_name)
if method is None or not method.enabled:
@@ -595,7 +595,7 @@ class AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name):
- if not re.match('^std::(__\d+::)?%s<.*>$' % self._name, class_type.tag):
+ if not re.match('^std::(__\\d+::)?%s<.*>$' % self._name, class_type.tag):
return None
method = self._method_dict.get(method_name)
if method is None or not method.enabled:
@@ -629,9 +629,9 @@ class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
def __call__(self, obj):
impl_type = obj.dereference().type.fields()[0].type.tag
# Check for new implementations first:
- if re.match('^std::(__\d+::)?__uniq_ptr_(data|impl)<.*>$', impl_type):
+ if re.match('^std::(__\\d+::)?__uniq_ptr_(data|impl)<.*>$', impl_type):
tuple_member = obj['_M_t']['_M_t']
- elif re.match('^std::(__\d+::)?tuple<.*>$', impl_type):
+ elif re.match('^std::(__\\d+::)?tuple<.*>$', impl_type):
tuple_member = obj['_M_t']
else:
return None
@@ -696,7 +696,7 @@ class UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name):
- if not re.match('^std::(__\d+::)?unique_ptr<.*>$', class_type.tag):
+ if not re.match('^std::(__\\d+::)?unique_ptr<.*>$', class_type.tag):
return None
method = self._method_dict.get(method_name)
if method is None or not method.enabled:
@@ -768,7 +768,7 @@ class SharedPtrSubscriptWorker(SharedPtrGetWorker):
def __call__(self, obj, index):
# Check bounds if _elem_type is an array of known bound
- m = re.match('.*\[(\d+)]$', str(self._elem_type))
+ m = re.match('.*\\[(\\d+)]$', str(self._elem_type))
if m and index >= int(m.group(1)):
raise IndexError('shared_ptr<%s> index "%d" should not be >= %d.' %
(self._elem_type, int(index), int(m.group(1))))
@@ -823,7 +823,7 @@ class SharedPtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
self.methods = [self._method_dict[m] for m in self._method_dict]
def match(self, class_type, method_name):
- if not re.match('^std::(__\d+::)?shared_ptr<.*>$', class_type.tag):
+ if not re.match('^std::(__\\d+::)?shared_ptr<.*>$', class_type.tag):
return None
method = self._method_dict.get(method_name)
if method is None or not method.enabled:
--
2.40.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 7/7] libstdc++: Use Python "not in" operator
2023-09-28 17:46 [PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers Tom Tromey
` (5 preceding siblings ...)
2023-09-28 17:46 ` [PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers Tom Tromey
@ 2023-09-28 17:46 ` Tom Tromey
2023-09-28 18:52 ` Jonathan Wakely
6 siblings, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 17:46 UTC (permalink / raw)
To: gcc-patches; +Cc: libstdc++, Tom Tromey
flake8 warns about code like
not something in "whatever"
Ordinarily in Python this should be written as:
something not in "whatever"
This patch makes this change.
libstdc++-v3/ChangeLog:
* python/libstdcxx/v6/printers.py (Printer.add_version)
(add_one_template_type_printer)
(FilteringTypePrinter.add_one_type_printer): Use Python
"not in" operator.
---
libstdc++-v3/python/libstdcxx/v6/printers.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index d125236b777..380426cd41e 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -2321,7 +2321,7 @@ class Printer(object):
# Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
def add_version(self, base, name, function):
self.add(base + name, function)
- if _versioned_namespace and not '__cxx11' in base:
+ if _versioned_namespace and '__cxx11' not in base:
vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' %
_versioned_namespace, base)
self.add(vbase + name, function)
@@ -2494,7 +2494,7 @@ def add_one_template_type_printer(obj, name, defargs):
printer = TemplateTypePrinter('std::__debug::'+name, defargs)
gdb.types.register_type_printer(obj, printer)
- if _versioned_namespace and not '__cxx11' in name:
+ if _versioned_namespace and '__cxx11' not in name:
# Add second type printer for same type in versioned namespace:
ns = 'std::' + _versioned_namespace
# PR 86112 Cannot use dict comprehension here:
@@ -2589,7 +2589,7 @@ class FilteringTypePrinter(object):
def add_one_type_printer(obj, template, name, targ1=None):
printer = FilteringTypePrinter('std::' + template, 'std::' + name, targ1)
gdb.types.register_type_printer(obj, printer)
- if _versioned_namespace and not '__cxx11' in template:
+ if _versioned_namespace and '__cxx11' not in template:
ns = 'std::' + _versioned_namespace
printer = FilteringTypePrinter(ns + template, ns + name, targ1)
gdb.types.register_type_printer(obj, printer)
--
2.40.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/7] libstdc++: Show full Python stack on error
2023-09-28 17:46 ` [PATCH 1/7] libstdc++: Show full Python stack on error Tom Tromey
@ 2023-09-28 18:49 ` Jonathan Wakely
0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Wakely @ 2023-09-28 18:49 UTC (permalink / raw)
To: Tom Tromey; +Cc: gcc-patches, libstdc++
[-- Attachment #1: Type: text/plain, Size: 1296 bytes --]
On Thu, 28 Sept 2023, 18:48 Tom Tromey via Libstdc++, <libstdc++@gcc.gnu.org>
wrote:
> This changes the libstdc++ test suite to arrange for gdb to show the
> full Python stack if any sort of Python exception occurs. This makes
> debugging the printers a little simpler.
>
Oh I wish I'd known about this sooner.
OK for trunk, thanks.
> libstdc++-v3/ChangeLog:
>
> * testsuite/lib/gdb-test.exp (gdb-test): Enable Python
> stack traces from gdb.
> ---
> libstdc++-v3/testsuite/lib/gdb-test.exp | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/libstdc++-v3/testsuite/lib/gdb-test.exp
> b/libstdc++-v3/testsuite/lib/gdb-test.exp
> index d8e572ef7b3..af7d970d388 100644
> --- a/libstdc++-v3/testsuite/lib/gdb-test.exp
> +++ b/libstdc++-v3/testsuite/lib/gdb-test.exp
> @@ -141,6 +141,8 @@ proc gdb-test { marker {selector {}} {load_xmethods 0}
> } {
> puts $fd "set auto-load no"
> # Now that we've disabled auto-load, it's safe to set the target file
> puts $fd "file ./$output_file"
> + # See the full backtrace of any failures.
> + puts $fd "set python print-stack full"
> # Load & register *our* copy of the pretty-printers
> puts $fd "source $printer_code"
> puts $fd "python register_libstdcxx_printers(None)"
> --
> 2.40.1
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers
2023-09-28 17:46 ` [PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers Tom Tromey
@ 2023-09-28 18:51 ` Jonathan Wakely
2023-09-28 19:11 ` Tom Tromey
0 siblings, 1 reply; 18+ messages in thread
From: Jonathan Wakely @ 2023-09-28 18:51 UTC (permalink / raw)
To: Tom Tromey; +Cc: gcc-patches, libstdc++
[-- Attachment #1: Type: text/plain, Size: 8674 bytes --]
On Thu, 28 Sept 2023, 18:50 Tom Tromey via Libstdc++, <libstdc++@gcc.gnu.org>
wrote:
> flake8 pointed out that some regexes in the pretty-printers are
> missing a backslash. This patch fixes these.
>
I already have a patch to use r'...' for these, so we only need the single
backslash.
I'm also refactoring all those re.match calls in xmethods.exp to use a
common function.
So please don't commit this one, I think it will be unnecessary in a couple
of hours.
> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py
> (StdExpAnyPrinter.__init__, StdExpOptionalPrinter.__init__):
> Add missing backslash.
> * python/libstdcxx/v6/xmethods.py
> (ArrayMethodsMatcher.match, DequeMethodsMatcher.match)
> (ForwardListMethodsMatcher.match, ListMethodsMatcher.match)
> (VectorMethodsMatcher.match)
> (AssociativeContainerMethodsMatcher.match)
> (UniquePtrGetWorker.__call__, UniquePtrMethodsMatcher.match)
> (SharedPtrSubscriptWorker.__call__)
> (SharedPtrMethodsMatcher.match): Add missing backslash.
> ---
> libstdc++-v3/python/libstdcxx/v6/printers.py | 6 +++---
> libstdc++-v3/python/libstdcxx/v6/xmethods.py | 22 ++++++++++----------
> 2 files changed, 14 insertions(+), 14 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index 94ac9232da7..d125236b777 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -1344,7 +1344,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
> def __init__(self, typename, val):
> self._typename = strip_versioned_namespace(typename)
> self._typename = re.sub(
> - '^std::experimental::fundamentals_v\d::',
> 'std::experimental::', self._typename, 1)
> + '^std::experimental::fundamentals_v\\d::',
> 'std::experimental::', self._typename, 1)
> self._val = val
> self._contained_type = None
> contained_value = None
> @@ -1377,7 +1377,7 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
> mgrtypes = []
> for s in strings:
> try:
> - x = re.sub("std::string(?!\w)", s, m.group(1))
> + x = re.sub("std::string(?!\\w)", s, m.group(1))
> # The following lookup might raise gdb.error if
> the
> # manager function was never instantiated for 's'
> in the
> # program, because there will be no such type.
> @@ -1425,7 +1425,7 @@ class
> StdExpOptionalPrinter(SingleObjContainerPrinter):
> def __init__(self, typename, val):
> typename = strip_versioned_namespace(typename)
> self._typename = re.sub(
> - '^std::(experimental::|)(fundamentals_v\d::|)(.*)',
> r'std::\1\3', typename, 1)
> + '^std::(experimental::|)(fundamentals_v\\d::|)(.*)',
> r'std::\1\3', typename, 1)
> payload = val['_M_payload']
> if self._typename.startswith('std::experimental'):
> engaged = val['_M_engaged']
> diff --git a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> index 025b1b86ed0..eafecbb148e 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/xmethods.py
> @@ -159,7 +159,7 @@ class ArrayMethodsMatcher(gdb.xmethod.XMethodMatcher):
> self.methods = [self._method_dict[m] for m in self._method_dict]
>
> def match(self, class_type, method_name):
> - if not re.match('^std::(__\d+::)?array<.*>$', class_type.tag):
> + if not re.match('^std::(__\\d+::)?array<.*>$', class_type.tag):
> return None
> method = self._method_dict.get(method_name)
> if method is None or not method.enabled:
> @@ -284,7 +284,7 @@ class DequeMethodsMatcher(gdb.xmethod.XMethodMatcher):
> self.methods = [self._method_dict[m] for m in self._method_dict]
>
> def match(self, class_type, method_name):
> - if not re.match('^std::(__\d+::)?deque<.*>$', class_type.tag):
> + if not re.match('^std::(__\\d+::)?deque<.*>$', class_type.tag):
> return None
> method = self._method_dict.get(method_name)
> if method is None or not method.enabled:
> @@ -332,7 +332,7 @@ class
> ForwardListMethodsMatcher(gdb.xmethod.XMethodMatcher):
> self.methods = [self._method_dict[m] for m in self._method_dict]
>
> def match(self, class_type, method_name):
> - if not re.match('^std::(__\d+::)?forward_list<.*>$',
> class_type.tag):
> + if not re.match('^std::(__\\d+::)?forward_list<.*>$',
> class_type.tag):
> return None
> method = self._method_dict.get(method_name)
> if method is None or not method.enabled:
> @@ -419,7 +419,7 @@ class ListMethodsMatcher(gdb.xmethod.XMethodMatcher):
> self.methods = [self._method_dict[m] for m in self._method_dict]
>
> def match(self, class_type, method_name):
> - if not re.match('^std::(__\d+::)?(__cxx11::)?list<.*>$',
> class_type.tag):
> + if not re.match('^std::(__\\d+::)?(__cxx11::)?list<.*>$',
> class_type.tag):
> return None
> method = self._method_dict.get(method_name)
> if method is None or not method.enabled:
> @@ -542,7 +542,7 @@ class VectorMethodsMatcher(gdb.xmethod.XMethodMatcher):
> self.methods = [self._method_dict[m] for m in self._method_dict]
>
> def match(self, class_type, method_name):
> - if not re.match('^std::(__\d+::)?vector<.*>$', class_type.tag):
> + if not re.match('^std::(__\\d+::)?vector<.*>$', class_type.tag):
> return None
> method = self._method_dict.get(method_name)
> if method is None or not method.enabled:
> @@ -595,7 +595,7 @@ class
> AssociativeContainerMethodsMatcher(gdb.xmethod.XMethodMatcher):
> self.methods = [self._method_dict[m] for m in self._method_dict]
>
> def match(self, class_type, method_name):
> - if not re.match('^std::(__\d+::)?%s<.*>$' % self._name,
> class_type.tag):
> + if not re.match('^std::(__\\d+::)?%s<.*>$' % self._name,
> class_type.tag):
> return None
> method = self._method_dict.get(method_name)
> if method is None or not method.enabled:
> @@ -629,9 +629,9 @@ class UniquePtrGetWorker(gdb.xmethod.XMethodWorker):
> def __call__(self, obj):
> impl_type = obj.dereference().type.fields()[0].type.tag
> # Check for new implementations first:
> - if re.match('^std::(__\d+::)?__uniq_ptr_(data|impl)<.*>$',
> impl_type):
> + if re.match('^std::(__\\d+::)?__uniq_ptr_(data|impl)<.*>$',
> impl_type):
> tuple_member = obj['_M_t']['_M_t']
> - elif re.match('^std::(__\d+::)?tuple<.*>$', impl_type):
> + elif re.match('^std::(__\\d+::)?tuple<.*>$', impl_type):
> tuple_member = obj['_M_t']
> else:
> return None
> @@ -696,7 +696,7 @@ class
> UniquePtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
> self.methods = [self._method_dict[m] for m in self._method_dict]
>
> def match(self, class_type, method_name):
> - if not re.match('^std::(__\d+::)?unique_ptr<.*>$',
> class_type.tag):
> + if not re.match('^std::(__\\d+::)?unique_ptr<.*>$',
> class_type.tag):
> return None
> method = self._method_dict.get(method_name)
> if method is None or not method.enabled:
> @@ -768,7 +768,7 @@ class SharedPtrSubscriptWorker(SharedPtrGetWorker):
>
> def __call__(self, obj, index):
> # Check bounds if _elem_type is an array of known bound
> - m = re.match('.*\[(\d+)]$', str(self._elem_type))
> + m = re.match('.*\\[(\\d+)]$', str(self._elem_type))
> if m and index >= int(m.group(1)):
> raise IndexError('shared_ptr<%s> index "%d" should not be >=
> %d.' %
> (self._elem_type, int(index),
> int(m.group(1))))
> @@ -823,7 +823,7 @@ class
> SharedPtrMethodsMatcher(gdb.xmethod.XMethodMatcher):
> self.methods = [self._method_dict[m] for m in self._method_dict]
>
> def match(self, class_type, method_name):
> - if not re.match('^std::(__\d+::)?shared_ptr<.*>$',
> class_type.tag):
> + if not re.match('^std::(__\\d+::)?shared_ptr<.*>$',
> class_type.tag):
> return None
> method = self._method_dict.get(method_name)
> if method is None or not method.enabled:
> --
> 2.40.1
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 7/7] libstdc++: Use Python "not in" operator
2023-09-28 17:46 ` [PATCH 7/7] libstdc++: Use Python "not in" operator Tom Tromey
@ 2023-09-28 18:52 ` Jonathan Wakely
0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Wakely @ 2023-09-28 18:52 UTC (permalink / raw)
To: Tom Tromey; +Cc: gcc-patches, libstdc++
[-- Attachment #1: Type: text/plain, Size: 2474 bytes --]
On Thu, 28 Sept 2023, 18:54 Tom Tromey via Libstdc++, <libstdc++@gcc.gnu.org>
wrote:
> flake8 warns about code like
>
> not something in "whatever"
>
> Ordinarily in Python this should be written as:
>
> something not in "whatever"
>
> This patch makes this change.
>
OK, thanks.
> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py (Printer.add_version)
> (add_one_template_type_printer)
> (FilteringTypePrinter.add_one_type_printer): Use Python
> "not in" operator.
> ---
> libstdc++-v3/python/libstdcxx/v6/printers.py | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index d125236b777..380426cd41e 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -2321,7 +2321,7 @@ class Printer(object):
> # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
> def add_version(self, base, name, function):
> self.add(base + name, function)
> - if _versioned_namespace and not '__cxx11' in base:
> + if _versioned_namespace and '__cxx11' not in base:
> vbase = re.sub('^(std|__gnu_cxx)::', r'\g<0>%s' %
> _versioned_namespace, base)
> self.add(vbase + name, function)
> @@ -2494,7 +2494,7 @@ def add_one_template_type_printer(obj, name,
> defargs):
> printer = TemplateTypePrinter('std::__debug::'+name, defargs)
> gdb.types.register_type_printer(obj, printer)
>
> - if _versioned_namespace and not '__cxx11' in name:
> + if _versioned_namespace and '__cxx11' not in name:
> # Add second type printer for same type in versioned namespace:
> ns = 'std::' + _versioned_namespace
> # PR 86112 Cannot use dict comprehension here:
> @@ -2589,7 +2589,7 @@ class FilteringTypePrinter(object):
> def add_one_type_printer(obj, template, name, targ1=None):
> printer = FilteringTypePrinter('std::' + template, 'std::' + name,
> targ1)
> gdb.types.register_type_printer(obj, printer)
> - if _versioned_namespace and not '__cxx11' in template:
> + if _versioned_namespace and '__cxx11' not in template:
> ns = 'std::' + _versioned_namespace
> printer = FilteringTypePrinter(ns + template, ns + name, targ1)
> gdb.types.register_type_printer(obj, printer)
> --
> 2.40.1
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/7] libstdc++: Remove unused locals from printers.py
2023-09-28 17:46 ` [PATCH 4/7] libstdc++: Remove unused locals from printers.py Tom Tromey
@ 2023-09-28 18:53 ` Jonathan Wakely
0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Wakely @ 2023-09-28 18:53 UTC (permalink / raw)
To: Tom Tromey; +Cc: gcc-patches, libstdc++
[-- Attachment #1: Type: text/plain, Size: 1643 bytes --]
On Thu, 28 Sept 2023, 18:50 Tom Tromey via Libstdc++, <libstdc++@gcc.gnu.org>
wrote:
> flake8 pointed out some unused local variables in the libstdc++
> pretty-printers. This removes them.
>
OK, thanks.
> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py
> (StdExpOptionalPrinter.__init__, lookup_node_type):
> Remove unused variables.
> ---
> libstdc++-v3/python/libstdcxx/v6/printers.py | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index 8d44244afb0..6bf4fe891fd 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -169,7 +169,7 @@ def lookup_node_type(nodename, containertype):
> valtype = valtype.strip_typedefs()
> try:
> return lookup_templ_spec(nodename, valtype)
> - except gdb.error as e:
> + except gdb.error:
> # For debug mode containers the node is in std::__cxx1998.
> if is_member_of_namespace(nodename, 'std'):
> if is_member_of_namespace(containertype, 'std::__cxx1998',
> @@ -1423,7 +1423,6 @@ class
> StdExpOptionalPrinter(SingleObjContainerPrinter):
> "Print a std::optional or std::experimental::optional"
>
> def __init__(self, typename, val):
> - valtype = self._recognize(val.type.template_argument(0))
> typename = strip_versioned_namespace(typename)
> self._typename = re.sub(
> '^std::(experimental::|)(fundamentals_v\d::|)(.*)',
> r'std::\1\3', typename, 1)
> --
> 2.40.1
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/7] libstdc++: Remove unused Python imports
2023-09-28 17:46 ` [PATCH 3/7] libstdc++: Remove unused Python imports Tom Tromey
@ 2023-09-28 18:53 ` Jonathan Wakely
0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Wakely @ 2023-09-28 18:53 UTC (permalink / raw)
To: Tom Tromey; +Cc: gcc-patches, libstdc++
[-- Attachment #1: Type: text/plain, Size: 1381 bytes --]
On Thu, 28 Sept 2023, 18:50 Tom Tromey via Libstdc++, <libstdc++@gcc.gnu.org>
wrote:
> flake8 pointed out some unused imports.
>
OK, thanks.
> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py: Don't import 'os'.
> * python/libstdcxx/v6/__init__.py: Don't import 'gdb'.
> ---
> libstdc++-v3/python/libstdcxx/v6/__init__.py | 2 --
> libstdc++-v3/python/libstdcxx/v6/printers.py | 1 -
> 2 files changed, 3 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/__init__.py
> b/libstdc++-v3/python/libstdcxx/v6/__init__.py
> index df654acd0c2..8b2cbc60a1b 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/__init__.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/__init__.py
> @@ -13,8 +13,6 @@
> # 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
> -
> # Load the xmethods if GDB supports them.
> def gdb_has_xmethods():
> try:
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index bbc4375541f..8d44244afb0 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -19,7 +19,6 @@ import gdb
> import itertools
> import re
> import sys
> -import os
> import errno
> import datetime
>
> --
> 2.40.1
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 5/7] libstdc++: Remove std_ratio_t_tuple
2023-09-28 17:46 ` [PATCH 5/7] libstdc++: Remove std_ratio_t_tuple Tom Tromey
@ 2023-09-28 19:01 ` Jonathan Wakely
0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Wakely @ 2023-09-28 19:01 UTC (permalink / raw)
To: Tom Tromey; +Cc: gcc-patches, libstdc++
[-- Attachment #1: Type: text/plain, Size: 1575 bytes --]
On Thu, 28 Sept 2023, 18:55 Tom Tromey via Libstdc++, <libstdc++@gcc.gnu.org>
wrote:
> This removes the std_ratio_t_tuple function from the Python
> pretty-printer code. It is not used. Apparently the relevant parts
> were moved to StdChronoDurationPrinter._ratio at some point in the
> past.
>
I think I added it at the same time as that printer, rather than moving it
there later. I don't remember if I wanted to replace the _ratio method with
that function, or vice versa, but it looks like I never finished whatever I
meant to do. Either way, we don't need to keep the unused function.
OK, thanks.
> libstdc++-v3/ChangeLog:
>
> * python/libstdcxx/v6/printers.py (std_ratio_t_tuple):
> Remove.
> ---
> libstdc++-v3/python/libstdcxx/v6/printers.py | 8 --------
> 1 file changed, 8 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index 6bf4fe891fd..94ac9232da7 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -1985,14 +1985,6 @@ class StdFormatArgsPrinter(printer_base):
> return "%s with %d arguments" % (typ, size)
>
>
> -def std_ratio_t_tuple(ratio_type):
> - # TODO use reduced period i.e. duration::period
> - period = self._val.type.template_argument(1)
> - num = period.template_argument(0)
> - den = period.template_argument(1)
> - return (num, den)
> -
> -
> class StdChronoDurationPrinter(printer_base):
> "Print a std::chrono::duration"
>
> --
> 2.40.1
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers
2023-09-28 18:51 ` Jonathan Wakely
@ 2023-09-28 19:11 ` Tom Tromey
0 siblings, 0 replies; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 19:11 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: Tom Tromey, gcc-patches, libstdc++
Jonathan> I already have a patch to use r'...' for these, so we only
Jonathan> need the single backslash.
Yeah, probably nicer.
Jonathan> So please don't commit this one, I think it will be
Jonathan> unnecessary in a couple of hours.
No problem, I'll drop it when I rebase on top of your changes.
Tom
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class
2023-09-28 17:46 ` [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class Tom Tromey
@ 2023-09-28 20:26 ` Jonathan Wakely
2023-09-28 20:38 ` Tom Tromey
0 siblings, 1 reply; 18+ messages in thread
From: Jonathan Wakely @ 2023-09-28 20:26 UTC (permalink / raw)
To: Tom Tromey; +Cc: gcc-patches, libstdc++
On Thu, 28 Sept 2023 at 18:50, Tom Tromey via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> GDB 14 will add a new ValuePrinter tag class that will be used to
> signal that pretty-printers will agree to the "extension protocol" --
> essentially that they will follow some simple namespace rules, so that
> GDB can add new methods over time.
>
> A couple new methods have already been added to GDB, to support DAP.
> While I haven't implemented these for any libstdc++ printers yet, this
> patch makes the basic conversion: printers derive from
> gdb.ValuePrinter if it is available, and all "non-standard" (that is,
> not specified by GDB) members of the various value-printing classes
> are renamed to have a leading underscore.
OK, thanks.
I've pushed the changes I wanted to make, so you'll have to rebase
your patches now, sorry.
> ---
> libstdc++-v3/python/libstdcxx/v6/printers.py | 1201 +++++++++---------
> 1 file changed, 605 insertions(+), 596 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index d60c8003a63..bbc4375541f 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -97,6 +97,12 @@ try:
> except ImportError:
> pass
>
> +# Use the base class if available.
> +if hasattr(gdb, 'ValuePrinter'):
> + printer_base = gdb.ValuePrinter
> +else:
> + printer_base = object
> +
> # Starting with the type ORIG, search for the member type NAME. This
> # handles searching upward through superclasses. This is needed to
> # work around http://sourceware.org/bugzilla/show_bug.cgi?id=13615.
> @@ -241,43 +247,43 @@ class SmartPtrIterator(Iterator):
> "An iterator for smart pointer types with a single 'child' value"
>
> def __init__(self, val):
> - self.val = val
> + self._val = val
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.val is None:
> + if self._val is None:
> raise StopIteration
> - self.val, val = None, self.val
> + self._val, val = None, self._val
> return ('get()', val)
>
>
> -class SharedPointerPrinter:
> +class SharedPointerPrinter(printer_base):
> "Print a shared_ptr, weak_ptr, atomic<shared_ptr>, or atomic<weak_ptr>"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> - self.pointer = val['_M_ptr']
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
> + self._pointer = val['_M_ptr']
>
> def children(self):
> - return SmartPtrIterator(self.pointer)
> + return SmartPtrIterator(self._pointer)
>
> # Return the _Sp_counted_base<>* that holds the refcounts.
> def _get_refcounts(self):
> - if self.typename == 'std::atomic':
> + if self._typename == 'std::atomic':
> # A tagged pointer is stored as uintptr_t.
> - ptr_val = self.val['_M_refcount']['_M_val']['_M_i']
> + ptr_val = self._val['_M_refcount']['_M_val']['_M_i']
> ptr_val = ptr_val - (ptr_val % 2) # clear lock bit
> - ptr_type = find_type(self.val['_M_refcount'].type, 'pointer')
> + ptr_type = find_type(self._val['_M_refcount'].type, 'pointer')
> return ptr_val.cast(ptr_type)
> - return self.val['_M_refcount']['_M_pi']
> + return self._val['_M_refcount']['_M_pi']
>
> def to_string(self):
> state = 'empty'
> refcounts = self._get_refcounts()
> - targ = self.val.type.template_argument(0)
> + targ = self._val.type.template_argument(0)
> targ = strip_versioned_namespace(str(targ))
>
> if refcounts != 0:
> @@ -288,7 +294,7 @@ class SharedPointerPrinter:
> else:
> state = 'use count %d, weak count %d' % (
> usecount, weakcount - 1)
> - return '%s<%s> (%s)' % (self.typename, targ, state)
> + return '%s<%s> (%s)' % (self._typename, targ, state)
>
>
> def _tuple_impl_get(val):
> @@ -347,17 +353,17 @@ def unique_ptr_get(val):
> return tuple_get(0, tuple_member)
>
>
> -class UniquePointerPrinter:
> +class UniquePointerPrinter(printer_base):
> "Print a unique_ptr"
>
> def __init__(self, typename, val):
> - self.val = val
> + self._val = val
>
> def children(self):
> - return SmartPtrIterator(unique_ptr_get(self.val))
> + return SmartPtrIterator(unique_ptr_get(self._val))
>
> def to_string(self):
> - return ('std::unique_ptr<%s>' % (str(self.val.type.template_argument(0))))
> + return ('std::unique_ptr<%s>' % (str(self._val.type.template_argument(0))))
>
>
> def get_value_from_aligned_membuf(buf, valtype):
> @@ -381,55 +387,56 @@ def get_value_from_list_node(node):
> raise ValueError("Unsupported implementation for %s" % str(node.type))
>
>
> -class StdListPrinter:
> +class StdListPrinter(printer_base):
> "Print a std::list"
>
> class _iterator(Iterator):
> def __init__(self, nodetype, head):
> - self.nodetype = nodetype
> - self.base = head['_M_next']
> - self.head = head.address
> - self.count = 0
> + 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:
> + 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
> + elt = self._base.cast(self._nodetype).dereference()
> + self._base = elt['_M_next']
> + count = self._count
> + self._count = self._count + 1
> val = get_value_from_list_node(elt)
> return ('[%d]' % count, val)
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def children(self):
> - nodetype = lookup_node_type('_List_node', self.val.type).pointer()
> - return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
> + nodetype = lookup_node_type('_List_node', self._val.type).pointer()
> + return self._iterator(nodetype, self._val['_M_impl']['_M_node'])
>
> def to_string(self):
> - headnode = self.val['_M_impl']['_M_node']
> + headnode = self._val['_M_impl']['_M_node']
> if headnode['_M_next'] == headnode.address:
> - return 'empty %s' % (self.typename)
> - return '%s' % (self.typename)
> + return 'empty %s' % (self._typename)
> + return '%s' % (self._typename)
>
>
> -class NodeIteratorPrinter:
> +class NodeIteratorPrinter(printer_base):
> def __init__(self, typename, val, contname, nodename):
> - self.val = val
> - self.typename = typename
> - self.contname = contname
> - self.nodetype = lookup_node_type(nodename, val.type)
> + self._val = val
> + self._typename = typename
> + self._contname = contname
> + self._nodetype = lookup_node_type(nodename, val.type)
>
> def to_string(self):
> - if not self.val['_M_node']:
> - return 'non-dereferenceable iterator for std::%s' % (self.contname)
> - node = self.val['_M_node'].cast(self.nodetype.pointer()).dereference()
> + if not self._val['_M_node']:
> + return 'non-dereferenceable iterator for std::%s' % (self._contname)
> + node = self._val['_M_node'].cast(
> + self._nodetype.pointer()).dereference()
> return str(get_value_from_list_node(node))
>
>
> @@ -448,163 +455,164 @@ class StdFwdListIteratorPrinter(NodeIteratorPrinter):
> '_Fwd_list_node')
>
>
> -class StdSlistPrinter:
> +class StdSlistPrinter(printer_base):
> "Print a __gnu_cxx::slist"
>
> class _iterator(Iterator):
> def __init__(self, nodetype, head):
> - self.nodetype = nodetype
> - self.base = head['_M_head']['_M_next']
> - self.count = 0
> + 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:
> + 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
> + 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, typename, val):
> - self.val = val
> + self._val = val
>
> def children(self):
> - nodetype = lookup_node_type('__gnu_cxx::_Slist_node', self.val.type)
> - return self._iterator(nodetype.pointer(), self.val)
> + nodetype = lookup_node_type('__gnu_cxx::_Slist_node', self._val.type)
> + return self._iterator(nodetype.pointer(), self._val)
>
> def to_string(self):
> - if self.val['_M_head']['_M_next'] == 0:
> + if self._val['_M_head']['_M_next'] == 0:
> return 'empty __gnu_cxx::slist'
> return '__gnu_cxx::slist'
>
>
> -class StdSlistIteratorPrinter:
> +class StdSlistIteratorPrinter(printer_base):
> "Print __gnu_cxx::slist::iterator"
>
> def __init__(self, typename, val):
> - self.val = val
> + self._val = val
>
> def to_string(self):
> - if not self.val['_M_node']:
> + if not self._val['_M_node']:
> return 'non-dereferenceable iterator for __gnu_cxx::slist'
> nodetype = lookup_node_type(
> - '__gnu_cxx::_Slist_node', self.val.type).pointer()
> - return str(self.val['_M_node'].cast(nodetype).dereference()['_M_data'])
> + '__gnu_cxx::_Slist_node', self._val.type).pointer()
> + return str(self._val['_M_node'].cast(nodetype).dereference()['_M_data'])
>
>
> -class StdVectorPrinter:
> +class StdVectorPrinter(printer_base):
> "Print a std::vector"
>
> class _iterator(Iterator):
> def __init__(self, start, finish, bitvec):
> - self.bitvec = bitvec
> + self._bitvec = bitvec
> if bitvec:
> - self.item = start['_M_p']
> - self.so = 0
> - self.finish = finish['_M_p']
> - self.fo = finish['_M_offset']
> - itype = self.item.dereference().type
> - self.isize = 8 * itype.sizeof
> + self._item = start['_M_p']
> + self._so = 0
> + self._finish = finish['_M_p']
> + self._fo = finish['_M_offset']
> + itype = self._item.dereference().type
> + self._isize = 8 * itype.sizeof
> else:
> - self.item = start
> - self.finish = finish
> - self.count = 0
> + self._item = start
> + self._finish = finish
> + self._count = 0
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - count = self.count
> - self.count = self.count + 1
> - if self.bitvec:
> - if self.item == self.finish and self.so >= self.fo:
> + count = self._count
> + self._count = self._count + 1
> + if self._bitvec:
> + if self._item == self._finish and self._so >= self._fo:
> raise StopIteration
> - elt = bool(self.item.dereference() & (1 << self.so))
> - self.so = self.so + 1
> - if self.so >= self.isize:
> - self.item = self.item + 1
> - self.so = 0
> + elt = bool(self._item.dereference() & (1 << self._so))
> + self._so = self._so + 1
> + if self._so >= self._isize:
> + self._item = self._item + 1
> + self._so = 0
> return ('[%d]' % count, elt)
> else:
> - if self.item == self.finish:
> + if self._item == self._finish:
> raise StopIteration
> - elt = self.item.dereference()
> - self.item = self.item + 1
> + elt = self._item.dereference()
> + self._item = self._item + 1
> return ('[%d]' % count, elt)
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> - self.is_bool = val.type.template_argument(0).code == gdb.TYPE_CODE_BOOL
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
> + self._is_bool = val.type.template_argument(
> + 0).code == gdb.TYPE_CODE_BOOL
>
> def children(self):
> - return self._iterator(self.val['_M_impl']['_M_start'],
> - self.val['_M_impl']['_M_finish'],
> - self.is_bool)
> + return self._iterator(self._val['_M_impl']['_M_start'],
> + self._val['_M_impl']['_M_finish'],
> + self._is_bool)
>
> 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']
> - if self.is_bool:
> - start = self.val['_M_impl']['_M_start']['_M_p']
> - finish = self.val['_M_impl']['_M_finish']['_M_p']
> - fo = self.val['_M_impl']['_M_finish']['_M_offset']
> + start = self._val['_M_impl']['_M_start']
> + finish = self._val['_M_impl']['_M_finish']
> + end = self._val['_M_impl']['_M_end_of_storage']
> + if self._is_bool:
> + start = self._val['_M_impl']['_M_start']['_M_p']
> + finish = self._val['_M_impl']['_M_finish']['_M_p']
> + fo = self._val['_M_impl']['_M_finish']['_M_offset']
> itype = start.dereference().type
> bl = 8 * itype.sizeof
> length = bl * (finish - start) + fo
> capacity = bl * (end - start)
> return ('%s<bool> of length %d, capacity %d'
> - % (self.typename, int(length), int(capacity)))
> + % (self._typename, int(length), int(capacity)))
> else:
> return ('%s of length %d, capacity %d'
> - % (self.typename, int(finish - start), int(end - start)))
> + % (self._typename, int(finish - start), int(end - start)))
>
> def display_hint(self):
> return 'array'
>
>
> -class StdVectorIteratorPrinter:
> +class StdVectorIteratorPrinter(printer_base):
> "Print std::vector::iterator"
>
> def __init__(self, typename, val):
> - self.val = val
> + self._val = val
>
> def to_string(self):
> - if not self.val['_M_current']:
> + if not self._val['_M_current']:
> return 'non-dereferenceable iterator for std::vector'
> - return str(self.val['_M_current'].dereference())
> + return str(self._val['_M_current'].dereference())
>
>
> -class StdBitIteratorPrinter:
> +class StdBitIteratorPrinter(printer_base):
> "Print std::vector<bool>'s _Bit_iterator and _Bit_const_iterator"
>
> def __init__(self, typename, val):
> - self.val = val
> + self._val = val
>
> def to_string(self):
> - if not self.val['_M_p']:
> + if not self._val['_M_p']:
> return 'non-dereferenceable iterator for std::vector<bool>'
> - return bool(self.val['_M_p'].dereference() & (1 << self.val['_M_offset']))
> + return bool(self._val['_M_p'].dereference() & (1 << self._val['_M_offset']))
>
>
> -class StdBitReferencePrinter:
> +class StdBitReferencePrinter(printer_base):
> "Print std::vector<bool>::reference"
>
> def __init__(self, typename, val):
> - self.val = val
> + self._val = val
>
> def to_string(self):
> - if not self.val['_M_p']:
> + if not self._val['_M_p']:
> return 'invalid std::vector<bool>::reference'
> - return bool(self.val['_M_p'].dereference() & (self.val['_M_mask']))
> + return bool(self._val['_M_p'].dereference() & (self._val['_M_mask']))
>
>
> -class StdTuplePrinter:
> +class StdTuplePrinter(printer_base):
> "Print a std::tuple"
>
> class _iterator(Iterator):
> @@ -621,25 +629,25 @@ class StdTuplePrinter:
> "Top of tuple tree does not consist of a single node.")
>
> def __init__(self, head):
> - self.head = head
> + self._head = head
>
> # Set the base class as the initial head of the
> # tuple.
> - nodes = self.head.type.fields()
> + nodes = self._head.type.fields()
> if self._is_nonempty_tuple(nodes):
> # Set the actual head to the first pair.
> - self.head = self.head.cast(nodes[0].type)
> - self.count = 0
> + self._head = self._head.cast(nodes[0].type)
> + self._count = 0
>
> def __iter__(self):
> return self
>
> def __next__(self):
> # Check for further recursions in the inheritance tree.
> - # For a GCC 5+ tuple self.head is None after visiting all nodes:
> - if not self.head:
> + # For a GCC 5+ tuple self._head is None after visiting all nodes:
> + if not self._head:
> raise StopIteration
> - nodes = self.head.type.fields()
> + nodes = self._head.type.fields()
> # For a GCC 4.x tuple there is a final node with no fields:
> if len(nodes) == 0:
> raise StopIteration
> @@ -650,8 +658,8 @@ class StdTuplePrinter:
>
> if len(nodes) == 1:
> # This is the last node of a GCC 5+ std::tuple.
> - impl = self.head.cast(nodes[0].type)
> - self.head = None
> + impl = self._head.cast(nodes[0].type)
> + self._head = None
> else:
> # Either a node before the last node, or the last node of
> # a GCC 4.x tuple (which has an empty parent).
> @@ -660,52 +668,52 @@ class StdTuplePrinter:
> # - Right node is the actual class contained in the tuple.
>
> # Process right node.
> - impl = self.head.cast(nodes[1].type)
> + impl = self._head.cast(nodes[1].type)
>
> # Process left node and set it as head.
> - self.head = self.head.cast(nodes[0].type)
> + self._head = self._head.cast(nodes[0].type)
>
> - self.count = self.count + 1
> + self._count = self._count + 1
>
> # Finally, check the implementation. If it is
> # wrapped in _M_head_impl return that, otherwise return
> # the value "as is".
> fields = impl.type.fields()
> if len(fields) < 1 or fields[0].name != "_M_head_impl":
> - return ('[%d]' % (self.count - 1), impl)
> + return ('[%d]' % (self._count - 1), impl)
> else:
> - return ('[%d]' % (self.count - 1), impl['_M_head_impl'])
> + return ('[%d]' % (self._count - 1), impl['_M_head_impl'])
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def children(self):
> - return self._iterator(self.val)
> + return self._iterator(self._val)
>
> def to_string(self):
> - if len(self.val.type.fields()) == 0:
> - return 'empty %s' % (self.typename)
> - return '%s containing' % (self.typename)
> + if len(self._val.type.fields()) == 0:
> + return 'empty %s' % (self._typename)
> + return '%s containing' % (self._typename)
>
>
> -class StdStackOrQueuePrinter:
> +class StdStackOrQueuePrinter(printer_base):
> "Print a std::stack or std::queue"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.visualizer = gdb.default_visualizer(val['c'])
> + self._typename = strip_versioned_namespace(typename)
> + self._visualizer = gdb.default_visualizer(val['c'])
>
> def children(self):
> - return self.visualizer.children()
> + return self._visualizer.children()
>
> def to_string(self):
> - return '%s wrapping: %s' % (self.typename,
> - self.visualizer.to_string())
> + return '%s wrapping: %s' % (self._typename,
> + self._visualizer.to_string())
>
> def display_hint(self):
> - if hasattr(self.visualizer, 'display_hint'):
> - return self.visualizer.display_hint()
> + if hasattr(self._visualizer, 'display_hint'):
> + return self._visualizer.display_hint()
> return None
>
>
> @@ -716,24 +724,24 @@ class RbtreeIterator(Iterator):
> """
>
> 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
> + 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)
> + return int(self._size)
>
> def __next__(self):
> - if self.count == self.size:
> + if self._count == self._size:
> raise StopIteration
> - result = self.node
> - self.count = self.count + 1
> - if self.count < self.size:
> + result = self._node
> + self._count = self._count + 1
> + if self._count < self._size:
> # Compute the next node.
> - node = self.node
> + node = self._node
> if node.dereference()['_M_right']:
> node = node.dereference()['_M_right']
> while node.dereference()['_M_left']:
> @@ -745,7 +753,7 @@ class RbtreeIterator(Iterator):
> parent = parent.dereference()['_M_parent']
> if node.dereference()['_M_right'] != parent:
> node = parent
> - self.node = node
> + self._node = node
> return result
>
>
> @@ -769,38 +777,38 @@ def get_value_from_Rb_tree_node(node):
> # class above.
>
>
> -class StdRbtreeIteratorPrinter:
> +class StdRbtreeIteratorPrinter(printer_base):
> "Print std::map::iterator, std::set::iterator, etc."
>
> def __init__(self, typename, val):
> - self.val = val
> - nodetype = lookup_node_type('_Rb_tree_node', self.val.type)
> - self.link_type = nodetype.pointer()
> + self._val = val
> + nodetype = lookup_node_type('_Rb_tree_node', self._val.type)
> + self._link_type = nodetype.pointer()
>
> def to_string(self):
> - if not self.val['_M_node']:
> + if not self._val['_M_node']:
> return 'non-dereferenceable iterator for associative container'
> - node = self.val['_M_node'].cast(self.link_type).dereference()
> + node = self._val['_M_node'].cast(self._link_type).dereference()
> return str(get_value_from_Rb_tree_node(node))
>
>
> -class StdDebugIteratorPrinter:
> +class StdDebugIteratorPrinter(printer_base):
> "Print a debug enabled version of an iterator"
>
> def __init__(self, typename, val):
> - self.val = val
> + self._val = val
>
> # Just strip away the encapsulating __gnu_debug::_Safe_iterator
> # and return the wrapped iterator value.
> def to_string(self):
> base_type = gdb.lookup_type('__gnu_debug::_Safe_iterator_base')
> - itype = self.val.type.template_argument(0)
> - safe_seq = self.val.cast(base_type)['_M_sequence']
> + itype = self._val.type.template_argument(0)
> + safe_seq = self._val.cast(base_type)['_M_sequence']
> if not safe_seq:
> - return str(self.val.cast(itype))
> - if self.val['_M_version'] != safe_seq['_M_version']:
> + return str(self._val.cast(itype))
> + if self._val['_M_version'] != safe_seq['_M_version']:
> return "invalid iterator"
> - return str(self.val.cast(itype))
> + return str(self._val.cast(itype))
>
>
> def num_elements(num):
> @@ -808,101 +816,101 @@ def num_elements(num):
> return '1 element' if num == 1 else '%d elements' % num
>
>
> -class StdMapPrinter:
> +class StdMapPrinter(printer_base):
> "Print a std::map or std::multimap"
>
> # Turn an RbtreeIterator into a pretty-print iterator.
> class _iter(Iterator):
> def __init__(self, rbiter, type):
> - self.rbiter = rbiter
> - self.count = 0
> - self.type = type
> + self._rbiter = rbiter
> + self._count = 0
> + self._type = type
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.count % 2 == 0:
> - n = next(self.rbiter)
> - n = n.cast(self.type).dereference()
> + if self._count % 2 == 0:
> + n = next(self._rbiter)
> + n = n.cast(self._type).dereference()
> n = get_value_from_Rb_tree_node(n)
> - self.pair = n
> + self._pair = n
> item = n['first']
> else:
> - item = self.pair['second']
> - result = ('[%d]' % self.count, item)
> - self.count = self.count + 1
> + item = self._pair['second']
> + result = ('[%d]' % self._count, item)
> + self._count = self._count + 1
> return result
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def to_string(self):
> - return '%s with %s' % (self.typename,
> - num_elements(len(RbtreeIterator(self.val))))
> + return '%s with %s' % (self._typename,
> + num_elements(len(RbtreeIterator(self._val))))
>
> def children(self):
> - node = lookup_node_type('_Rb_tree_node', self.val.type).pointer()
> - return self._iter(RbtreeIterator(self.val), node)
> + node = lookup_node_type('_Rb_tree_node', self._val.type).pointer()
> + return self._iter(RbtreeIterator(self._val), node)
>
> def display_hint(self):
> return 'map'
>
>
> -class StdSetPrinter:
> +class StdSetPrinter(printer_base):
> "Print a std::set or std::multiset"
>
> # Turn an RbtreeIterator into a pretty-print iterator.
> class _iter(Iterator):
> def __init__(self, rbiter, type):
> - self.rbiter = rbiter
> - self.count = 0
> - self.type = type
> + self._rbiter = rbiter
> + self._count = 0
> + self._type = type
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - item = next(self.rbiter)
> - item = item.cast(self.type).dereference()
> + item = next(self._rbiter)
> + item = item.cast(self._type).dereference()
> item = get_value_from_Rb_tree_node(item)
> # FIXME: this is weird ... what to do?
> # Maybe a 'set' display hint?
> - result = ('[%d]' % self.count, item)
> - self.count = self.count + 1
> + result = ('[%d]' % self._count, item)
> + self._count = self._count + 1
> return result
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def to_string(self):
> - return '%s with %s' % (self.typename,
> - num_elements(len(RbtreeIterator(self.val))))
> + return '%s with %s' % (self._typename,
> + num_elements(len(RbtreeIterator(self._val))))
>
> def children(self):
> - node = lookup_node_type('_Rb_tree_node', self.val.type).pointer()
> - return self._iter(RbtreeIterator(self.val), node)
> + node = lookup_node_type('_Rb_tree_node', self._val.type).pointer()
> + return self._iter(RbtreeIterator(self._val), node)
>
>
> -class StdBitsetPrinter:
> +class StdBitsetPrinter(printer_base):
> "Print a std::bitset"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + 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 '%s' % (self.typename)
> + return '%s' % (self._typename)
>
> def children(self):
> try:
> # An empty bitset may not have any members which will
> # result in an exception being thrown.
> - words = self.val['_M_w']
> + words = self._val['_M_w']
> except:
> return []
>
> @@ -933,102 +941,102 @@ class StdBitsetPrinter:
> return result
>
>
> -class StdDequePrinter:
> +class StdDequePrinter(printer_base):
> "Print a std::deque"
>
> class _iter(Iterator):
> 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
> + 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:
> + if self._p == self._last:
> raise StopIteration
>
> - result = ('[%d]' % self.count, self.p.dereference())
> - self.count = self.count + 1
> + 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:
> + 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
> + self._node = self._node + 1
> + self._p = self._node[0]
> + self._end = self._p + self._buffer_size
>
> return result
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> - self.elttype = val.type.template_argument(0)
> - size = self.elttype.sizeof
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
> + self._elttype = val.type.template_argument(0)
> + size = self._elttype.sizeof
> if size < 512:
> - self.buffer_size = int(512 / size)
> + self._buffer_size = int(512 / size)
> else:
> - self.buffer_size = 1
> + self._buffer_size = 1
>
> def to_string(self):
> - start = self.val['_M_impl']['_M_start']
> - end = self.val['_M_impl']['_M_finish']
> + 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
> + size = self._buffer_size * delta_n + delta_s + delta_e
>
> - return '%s with %s' % (self.typename, num_elements(long(size)))
> + return '%s with %s' % (self._typename, num_elements(long(size)))
>
> def children(self):
> - start = self.val['_M_impl']['_M_start']
> - end = self.val['_M_impl']['_M_finish']
> + 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)
> + end['_M_cur'], self._buffer_size)
>
> def display_hint(self):
> return 'array'
>
>
> -class StdDequeIteratorPrinter:
> +class StdDequeIteratorPrinter(printer_base):
> "Print std::deque::iterator"
>
> def __init__(self, typename, val):
> - self.val = val
> + self._val = val
>
> def to_string(self):
> - if not self.val['_M_cur']:
> + if not self._val['_M_cur']:
> return 'non-dereferenceable iterator for std::deque'
> - return str(self.val['_M_cur'].dereference())
> + return str(self._val['_M_cur'].dereference())
>
>
> -class StdStringPrinter:
> +class StdStringPrinter(printer_base):
> "Print a std::basic_string of some kind"
>
> def __init__(self, typename, val):
> - self.val = val
> - self.new_string = typename.find("::__cxx11::basic_string") != -1
> + self._val = val
> + self._new_string = typename.find("::__cxx11::basic_string") != -1
>
> def to_string(self):
> # Make sure &string works, too.
> - type = self.val.type
> + type = self._val.type
> if type.code == gdb.TYPE_CODE_REF:
> type = type.target()
>
> # Calculate the length of the string so that to_string returns
> # the string according to length, not according to first null
> # encountered.
> - ptr = self.val['_M_dataplus']['_M_p']
> - if self.new_string:
> - length = self.val['_M_string_length']
> + ptr = self._val['_M_dataplus']['_M_p']
> + if self._new_string:
> + length = self._val['_M_string_length']
> # https://sourceware.org/bugzilla/show_bug.cgi?id=17728
> ptr = ptr.cast(ptr.type.strip_typedefs())
> else:
> @@ -1052,173 +1060,173 @@ def access_streambuf_ptrs(streambuf):
> return pbase, pptr, egptr
>
>
> -class StdStringBufPrinter:
> +class StdStringBufPrinter(printer_base):
> "Print a std::basic_stringbuf"
>
> def __init__(self, _, val):
> - self.val = val
> + self._val = val
>
> def to_string(self):
> - (pbase, pptr, egptr) = access_streambuf_ptrs(self.val)
> + (pbase, pptr, egptr) = access_streambuf_ptrs(self._val)
> # Logic from basic_stringbuf::_M_high_mark()
> if pptr:
> if not egptr or pptr > egptr:
> return pbase.string(length=pptr - pbase)
> else:
> return pbase.string(length=egptr - pbase)
> - return self.val['_M_string']
> + return self._val['_M_string']
>
> def display_hint(self):
> return 'string'
>
>
> -class StdStringStreamPrinter:
> +class StdStringStreamPrinter(printer_base):
> "Print a std::basic_stringstream"
>
> def __init__(self, typename, val):
> - self.val = val
> - self.typename = typename
> + self._val = val
> + self._typename = typename
>
> # Check if the stream was redirected:
> # This is essentially: val['_M_streambuf'] == val['_M_stringbuf'].address
> # However, GDB can't resolve the virtual inheritance, so we do that manually
> basetype = [f.type for f in val.type.fields() if f.is_base_class][0]
> gdb.set_convenience_variable('__stream', val.cast(basetype).address)
> - self.streambuf = gdb.parse_and_eval('$__stream->rdbuf()')
> - self.was_redirected = self.streambuf != val['_M_stringbuf'].address
> + self._streambuf = gdb.parse_and_eval('$__stream->rdbuf()')
> + self._was_redirected = self._streambuf != val['_M_stringbuf'].address
>
> def to_string(self):
> - if self.was_redirected:
> - return "%s redirected to %s" % (self.typename, self.streambuf.dereference())
> - return self.val['_M_stringbuf']
> + if self._was_redirected:
> + return "%s redirected to %s" % (self._typename, self._streambuf.dereference())
> + return self._val['_M_stringbuf']
>
> def display_hint(self):
> - if self.was_redirected:
> + if self._was_redirected:
> return None
> return 'string'
>
>
> class Tr1HashtableIterator(Iterator):
> def __init__(self, hashtable):
> - self.buckets = hashtable['_M_buckets']
> - self.bucket = 0
> - self.bucket_count = hashtable['_M_bucket_count']
> - self.node_type = find_type(hashtable.type, '_Node').pointer()
> - self.node = 0
> - while self.bucket != self.bucket_count:
> - self.node = self.buckets[self.bucket]
> - if self.node:
> + self._buckets = hashtable['_M_buckets']
> + self._bucket = 0
> + self._bucket_count = hashtable['_M_bucket_count']
> + self._node_type = find_type(hashtable.type, '_Node').pointer()
> + self._node = 0
> + while self._bucket != self._bucket_count:
> + self._node = self._buckets[self._bucket]
> + if self._node:
> break
> - self.bucket = self.bucket + 1
> + self._bucket = self._bucket + 1
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.node == 0:
> + if self._node == 0:
> raise StopIteration
> - node = self.node.cast(self.node_type)
> + node = self._node.cast(self._node_type)
> result = node.dereference()['_M_v']
> - self.node = node.dereference()['_M_next']
> - if self.node == 0:
> - self.bucket = self.bucket + 1
> - while self.bucket != self.bucket_count:
> - self.node = self.buckets[self.bucket]
> - if self.node:
> + self._node = node.dereference()['_M_next']
> + if self._node == 0:
> + self._bucket = self._bucket + 1
> + while self._bucket != self._bucket_count:
> + self._node = self._buckets[self._bucket]
> + if self._node:
> break
> - self.bucket = self.bucket + 1
> + self._bucket = self._bucket + 1
> return result
>
>
> class StdHashtableIterator(Iterator):
> def __init__(self, hashtable):
> - self.node = hashtable['_M_before_begin']['_M_nxt']
> + self._node = hashtable['_M_before_begin']['_M_nxt']
> valtype = hashtable.type.template_argument(1)
> cached = hashtable.type.template_argument(9).template_argument(0)
> node_type = lookup_templ_spec('std::__detail::_Hash_node', str(valtype),
> 'true' if cached else 'false')
> - self.node_type = node_type.pointer()
> + self._node_type = node_type.pointer()
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.node == 0:
> + if self._node == 0:
> raise StopIteration
> - elt = self.node.cast(self.node_type).dereference()
> - self.node = elt['_M_nxt']
> + elt = self._node.cast(self._node_type).dereference()
> + self._node = elt['_M_nxt']
> valptr = elt['_M_storage'].address
> valptr = valptr.cast(elt.type.template_argument(0).pointer())
> return valptr.dereference()
>
>
> -class Tr1UnorderedSetPrinter:
> +class Tr1UnorderedSetPrinter(printer_base):
> "Print a std::unordered_set or tr1::unordered_set"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> - def hashtable(self):
> - if self.typename.startswith('std::tr1'):
> - return self.val
> - return self.val['_M_h']
> + def _hashtable(self):
> + if self._typename.startswith('std::tr1'):
> + return self._val
> + return self._val['_M_h']
>
> def to_string(self):
> - count = self.hashtable()['_M_element_count']
> - return '%s with %s' % (self.typename, num_elements(count))
> + count = self._hashtable()['_M_element_count']
> + return '%s with %s' % (self._typename, num_elements(count))
>
> @staticmethod
> - def format_count(i):
> + def _format_count(i):
> return '[%d]' % i
>
> def children(self):
> - counter = imap(self.format_count, itertools.count())
> - if self.typename.startswith('std::tr1'):
> - return izip(counter, Tr1HashtableIterator(self.hashtable()))
> - return izip(counter, StdHashtableIterator(self.hashtable()))
> + counter = imap(self._format_count, itertools.count())
> + if self._typename.startswith('std::tr1'):
> + return izip(counter, Tr1HashtableIterator(self._hashtable()))
> + return izip(counter, StdHashtableIterator(self._hashtable()))
>
>
> -class Tr1UnorderedMapPrinter:
> +class Tr1UnorderedMapPrinter(printer_base):
> "Print a std::unordered_map or tr1::unordered_map"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> - def hashtable(self):
> - if self.typename.startswith('std::tr1'):
> - return self.val
> - return self.val['_M_h']
> + def _hashtable(self):
> + if self._typename.startswith('std::tr1'):
> + return self._val
> + return self._val['_M_h']
>
> def to_string(self):
> - count = self.hashtable()['_M_element_count']
> - return '%s with %s' % (self.typename, num_elements(count))
> + count = self._hashtable()['_M_element_count']
> + return '%s with %s' % (self._typename, num_elements(count))
>
> @staticmethod
> - def flatten(list):
> + def _flatten(list):
> for elt in list:
> for i in elt:
> yield i
>
> @staticmethod
> - def format_one(elt):
> + def _format_one(elt):
> return (elt['first'], elt['second'])
>
> @staticmethod
> - def format_count(i):
> + def _format_count(i):
> return '[%d]' % i
>
> def children(self):
> - counter = imap(self.format_count, itertools.count())
> + counter = imap(self._format_count, itertools.count())
> # Map over the hash table and flatten the result.
> - if self.typename.startswith('std::tr1'):
> - data = self.flatten(
> - imap(self.format_one, Tr1HashtableIterator(self.hashtable())))
> + if self._typename.startswith('std::tr1'):
> + data = self._flatten(
> + imap(self._format_one, Tr1HashtableIterator(self._hashtable())))
> # Zip the two iterators together.
> return izip(counter, data)
> - data = self.flatten(
> - imap(self.format_one, StdHashtableIterator(self.hashtable())))
> + data = self._flatten(
> + imap(self._format_one, StdHashtableIterator(self._hashtable())))
> # Zip the two iterators together.
> return izip(counter, data)
>
> @@ -1226,50 +1234,50 @@ class Tr1UnorderedMapPrinter:
> return 'map'
>
>
> -class StdForwardListPrinter:
> +class StdForwardListPrinter(printer_base):
> "Print a std::forward_list"
>
> class _iterator(Iterator):
> def __init__(self, nodetype, head):
> - self.nodetype = nodetype
> - self.base = head['_M_next']
> - self.count = 0
> + self._nodetype = nodetype
> + self._base = head['_M_next']
> + self._count = 0
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.base == 0:
> + 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
> + elt = self._base.cast(self._nodetype).dereference()
> + self._base = elt['_M_next']
> + count = self._count
> + self._count = self._count + 1
> valptr = elt['_M_storage'].address
> valptr = valptr.cast(elt.type.template_argument(0).pointer())
> return ('[%d]' % count, valptr.dereference())
>
> def __init__(self, typename, val):
> - self.val = val
> - self.typename = strip_versioned_namespace(typename)
> + self._val = val
> + self._typename = strip_versioned_namespace(typename)
>
> def children(self):
> - nodetype = lookup_node_type('_Fwd_list_node', self.val.type).pointer()
> - return self._iterator(nodetype, self.val['_M_impl']['_M_head'])
> + nodetype = lookup_node_type('_Fwd_list_node', self._val.type).pointer()
> + return self._iterator(nodetype, self._val['_M_impl']['_M_head'])
>
> def to_string(self):
> - if self.val['_M_impl']['_M_head']['_M_next'] == 0:
> - return 'empty %s' % self.typename
> - return '%s' % self.typename
> + if self._val['_M_impl']['_M_head']['_M_next'] == 0:
> + return 'empty %s' % self._typename
> + return '%s' % self._typename
>
>
> -class SingleObjContainerPrinter(object):
> +class SingleObjContainerPrinter(printer_base):
> "Base class for printers of containers of single objects"
>
> def __init__(self, val, viz, hint=None):
> - self.contained_value = val
> - self.visualizer = viz
> - self.hint = hint
> + self._contained_value = val
> + self._visualizer = viz
> + self._hint = hint
>
> def _recognize(self, type):
> """Return TYPE as a string after applying type printers"""
> @@ -1281,30 +1289,30 @@ class SingleObjContainerPrinter(object):
>
> class _contained(Iterator):
> def __init__(self, val):
> - self.val = val
> + self._val = val
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.val is None:
> + if self._val is None:
> raise StopIteration
> - retval = self.val
> - self.val = None
> + retval = self._val
> + self._val = None
> return ('[contained value]', retval)
>
> def children(self):
> - if self.contained_value is None:
> + if self._contained_value is None:
> return self._contained(None)
> - if hasattr(self.visualizer, 'children'):
> - return self.visualizer.children()
> - return self._contained(self.contained_value)
> + if hasattr(self._visualizer, 'children'):
> + return self._visualizer.children()
> + return self._contained(self._contained_value)
>
> def display_hint(self):
> # if contained value is a map we want to display in the same way
> - if hasattr(self.visualizer, 'children') and hasattr(self.visualizer, 'display_hint'):
> - return self.visualizer.display_hint()
> - return self.hint
> + if hasattr(self._visualizer, 'children') and hasattr(self._visualizer, 'display_hint'):
> + return self._visualizer.display_hint()
> + return self._hint
>
>
> def function_pointer_to_name(f):
> @@ -1335,24 +1343,24 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
> "Print a std::any or std::experimental::any"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.typename = re.sub(
> - '^std::experimental::fundamentals_v\d::', 'std::experimental::', self.typename, 1)
> - self.val = val
> - self.contained_type = None
> + self._typename = strip_versioned_namespace(typename)
> + self._typename = re.sub(
> + '^std::experimental::fundamentals_v\d::', 'std::experimental::', self._typename, 1)
> + self._val = val
> + self._contained_type = None
> contained_value = None
> visualizer = None
> - mgr = self.val['_M_manager']
> + mgr = self._val['_M_manager']
> if mgr != 0:
> func = function_pointer_to_name(mgr)
> if not func:
> - raise ValueError(
> - "Invalid function pointer in %s" % (self.typename))
> + raise ValueError("Invalid function pointer in %s" %
> + (self._typename))
> rx = r"""({0}::_Manager_\w+<.*>)::_S_manage\((enum )?{0}::_Op, (const {0}|{0} const) ?\*, (union )?{0}::_Arg ?\*\)""".format(typename)
> m = re.match(rx, func)
> if not m:
> raise ValueError(
> - "Unknown manager function in %s" % self.typename)
> + "Unknown manager function in %s" % self._typename)
>
> mgrname = m.group(1)
> # FIXME need to expand 'std::string' so that gdb.lookup_type works
> @@ -1388,27 +1396,27 @@ class StdExpAnyPrinter(SingleObjContainerPrinter):
> mgrtype = mgrtypes[0]
> else:
> mgrtype = gdb.lookup_type(mgrname)
> - self.contained_type = mgrtype.template_argument(0)
> + self._contained_type = mgrtype.template_argument(0)
> valptr = None
> if '::_Manager_internal' in mgrname:
> - valptr = self.val['_M_storage']['_M_buffer'].address
> + valptr = self._val['_M_storage']['_M_buffer'].address
> elif '::_Manager_external' in mgrname:
> - valptr = self.val['_M_storage']['_M_ptr']
> + valptr = self._val['_M_storage']['_M_ptr']
> else:
> raise ValueError(
> - "Unknown manager function in %s" % self.typename)
> + "Unknown manager function in %s" % self._typename)
> contained_value = valptr.cast(
> - self.contained_type.pointer()).dereference()
> + self._contained_type.pointer()).dereference()
> visualizer = gdb.default_visualizer(contained_value)
> super(StdExpAnyPrinter, self).__init__(contained_value, visualizer)
>
> def to_string(self):
> - if self.contained_type is None:
> - return '%s [no contained value]' % self.typename
> - desc = "%s containing " % self.typename
> - if hasattr(self.visualizer, 'children'):
> - return desc + self.visualizer.to_string()
> - valtype = self._recognize(self.contained_type)
> + if self._contained_type is None:
> + return '%s [no contained value]' % self._typename
> + desc = "%s containing " % self._typename
> + if hasattr(self._visualizer, 'children'):
> + return desc + self._visualizer.to_string()
> + valtype = self._recognize(self._contained_type)
> return desc + strip_versioned_namespace(str(valtype))
>
>
> @@ -1418,10 +1426,10 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
> def __init__(self, typename, val):
> valtype = self._recognize(val.type.template_argument(0))
> typename = strip_versioned_namespace(typename)
> - self.typename = re.sub(
> + self._typename = re.sub(
> '^std::(experimental::|)(fundamentals_v\d::|)(.*)', r'std::\1\3', typename, 1)
> payload = val['_M_payload']
> - if self.typename.startswith('std::experimental'):
> + if self._typename.startswith('std::experimental'):
> engaged = val['_M_engaged']
> contained_value = payload
> else:
> @@ -1439,12 +1447,12 @@ class StdExpOptionalPrinter(SingleObjContainerPrinter):
> contained_value, visualizer)
>
> def to_string(self):
> - if self.contained_value is None:
> - return "%s [no contained value]" % self.typename
> - if hasattr(self.visualizer, 'children'):
> - return "%s containing %s" % (self.typename,
> - self.visualizer.to_string())
> - return self.typename
> + if self._contained_value is None:
> + return "%s [no contained value]" % self._typename
> + if hasattr(self._visualizer, 'children'):
> + return "%s containing %s" % (self._typename,
> + self._visualizer.to_string())
> + return self._typename
>
>
> class StdVariantPrinter(SingleObjContainerPrinter):
> @@ -1452,83 +1460,83 @@ class StdVariantPrinter(SingleObjContainerPrinter):
>
> def __init__(self, typename, val):
> alternatives = get_template_arg_list(val.type)
> - self.typename = strip_versioned_namespace(typename)
> - self.index = val['_M_index']
> - if self.index >= len(alternatives):
> - self.contained_type = None
> + self._typename = strip_versioned_namespace(typename)
> + self._index = val['_M_index']
> + if self._index >= len(alternatives):
> + self._contained_type = None
> contained_value = None
> visualizer = None
> else:
> - self.contained_type = alternatives[int(self.index)]
> + self._contained_type = alternatives[int(self._index)]
> addr = val['_M_u']['_M_first']['_M_storage'].address
> contained_value = addr.cast(
> - self.contained_type.pointer()).dereference()
> + self._contained_type.pointer()).dereference()
> visualizer = gdb.default_visualizer(contained_value)
> super(StdVariantPrinter, self).__init__(
> contained_value, visualizer, 'array')
>
> def to_string(self):
> - if self.contained_value is None:
> - return "%s [no contained value]" % self.typename
> - if hasattr(self.visualizer, 'children'):
> - return "%s [index %d] containing %s" % (self.typename, self.index,
> - self.visualizer.to_string())
> - return "%s [index %d]" % (self.typename, self.index)
> + if self._contained_value is None:
> + return "%s [no contained value]" % self._typename
> + if hasattr(self._visualizer, 'children'):
> + return "%s [index %d] containing %s" % (self._typename, self._index,
> + self._visualizer.to_string())
> + return "%s [index %d]" % (self._typename, self._index)
>
>
> class StdNodeHandlePrinter(SingleObjContainerPrinter):
> "Print a container node handle"
>
> def __init__(self, typename, val):
> - self.value_type = val.type.template_argument(1)
> + self._value_type = val.type.template_argument(1)
> nodetype = val.type.template_argument(2).template_argument(0)
> - self.is_rb_tree_node = is_specialization_of(
> + self._is_rb_tree_node = is_specialization_of(
> nodetype.name, '_Rb_tree_node')
> - self.is_map_node = val.type.template_argument(0) != self.value_type
> + self._is_map_node = val.type.template_argument(0) != self._value_type
> nodeptr = val['_M_ptr']
> if nodeptr:
> - if self.is_rb_tree_node:
> + if self._is_rb_tree_node:
> contained_value = get_value_from_Rb_tree_node(
> nodeptr.dereference())
> else:
> contained_value = get_value_from_aligned_membuf(nodeptr['_M_storage'],
> - self.value_type)
> + self._value_type)
> visualizer = gdb.default_visualizer(contained_value)
> else:
> contained_value = None
> visualizer = None
> optalloc = val['_M_alloc']
> - self.alloc = optalloc['_M_payload'] if optalloc['_M_engaged'] else None
> + self._alloc = optalloc['_M_payload'] if optalloc['_M_engaged'] else None
> super(StdNodeHandlePrinter, self).__init__(contained_value, visualizer,
> 'array')
>
> def to_string(self):
> desc = 'node handle for '
> - if not self.is_rb_tree_node:
> + if not self._is_rb_tree_node:
> desc += 'unordered '
> - if self.is_map_node:
> + if self._is_map_node:
> desc += 'map'
> else:
> desc += 'set'
>
> - if self.contained_value:
> + if self._contained_value:
> desc += ' with element'
> - if hasattr(self.visualizer, 'children'):
> - return "%s = %s" % (desc, self.visualizer.to_string())
> + if hasattr(self._visualizer, 'children'):
> + return "%s = %s" % (desc, self._visualizer.to_string())
> return desc
> else:
> return 'empty %s' % desc
>
>
> -class StdExpStringViewPrinter:
> +class StdExpStringViewPrinter(printer_base):
> "Print a std::basic_string_view or std::experimental::basic_string_view"
>
> def __init__(self, typename, val):
> - self.val = val
> + self._val = val
>
> def to_string(self):
> - ptr = self.val['_M_str']
> - len = self.val['_M_len']
> + ptr = self._val['_M_str']
> + len = self._val['_M_len']
> if hasattr(ptr, "lazy_string"):
> return ptr.lazy_string(length=len)
> return ptr.string(length=len)
> @@ -1537,18 +1545,18 @@ class StdExpStringViewPrinter:
> return 'string'
>
>
> -class StdExpPathPrinter:
> +class StdExpPathPrinter(printer_base):
> "Print a std::experimental::filesystem::path"
>
> def __init__(self, typename, val):
> - self.val = val
> - self.typename = typename
> - start = self.val['_M_cmpts']['_M_impl']['_M_start']
> - finish = self.val['_M_cmpts']['_M_impl']['_M_finish']
> - self.num_cmpts = int(finish - start)
> + self._val = val
> + self._typename = typename
> + start = self._val['_M_cmpts']['_M_impl']['_M_start']
> + finish = self._val['_M_cmpts']['_M_impl']['_M_finish']
> + self._num_cmpts = int(finish - start)
>
> def _path_type(self):
> - t = str(self.val['_M_type'])
> + t = str(self._val['_M_type'])
> if t[-9:] == '_Root_dir':
> return "root-directory"
> if t[-10:] == '_Root_name':
> @@ -1556,8 +1564,8 @@ class StdExpPathPrinter:
> return None
>
> def to_string(self):
> - path = "%s" % self.val['_M_pathname']
> - if self.num_cmpts == 0:
> + path = "%s" % self._val['_M_pathname']
> + if self._num_cmpts == 0:
> t = self._path_type()
> if t:
> path = '%s [%s]' % (path, t)
> @@ -1565,46 +1573,46 @@ class StdExpPathPrinter:
>
> class _iterator(Iterator):
> def __init__(self, cmpts, pathtype):
> - self.pathtype = pathtype
> - self.item = cmpts['_M_impl']['_M_start']
> - self.finish = cmpts['_M_impl']['_M_finish']
> - self.count = 0
> + self._pathtype = pathtype
> + self._item = cmpts['_M_impl']['_M_start']
> + self._finish = cmpts['_M_impl']['_M_finish']
> + self._count = 0
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.item == self.finish:
> + if self._item == self._finish:
> raise StopIteration
> - item = self.item.dereference()
> - count = self.count
> - self.count = self.count + 1
> - self.item = self.item + 1
> + item = self._item.dereference()
> + count = self._count
> + self._count = self._count + 1
> + self._item = self._item + 1
> path = item['_M_pathname']
> - t = StdExpPathPrinter(self.pathtype, item)._path_type()
> + t = StdExpPathPrinter(self._pathtype, item)._path_type()
> if not t:
> t = count
> return ('[%s]' % t, path)
>
> def children(self):
> - return self._iterator(self.val['_M_cmpts'], self.typename)
> + return self._iterator(self._val['_M_cmpts'], self._typename)
>
>
> -class StdPathPrinter:
> +class StdPathPrinter(printer_base):
> "Print a std::filesystem::path"
>
> def __init__(self, typename, val):
> - self.val = val
> - self.typename = typename
> - impl = unique_ptr_get(self.val['_M_cmpts']['_M_impl'])
> - self.type = impl.cast(gdb.lookup_type('uintptr_t')) & 3
> - if self.type == 0:
> - self.impl = impl
> + self._val = val
> + self._typename = typename
> + impl = unique_ptr_get(self._val['_M_cmpts']['_M_impl'])
> + self._type = impl.cast(gdb.lookup_type('uintptr_t')) & 3
> + if self._type == 0:
> + self._impl = impl
> else:
> - self.impl = None
> + self._impl = None
>
> def _path_type(self):
> - t = str(self.type.cast(gdb.lookup_type(self.typename + '::_Type')))
> + t = str(self._type.cast(gdb.lookup_type(self._typename + '::_Type')))
> if t[-9:] == '_Root_dir':
> return "root-directory"
> if t[-10:] == '_Root_name':
> @@ -1612,8 +1620,8 @@ class StdPathPrinter:
> return None
>
> def to_string(self):
> - path = "%s" % self.val['_M_pathname']
> - if self.type != 0:
> + path = "%s" % self._val['_M_pathname']
> + if self._type != 0:
> t = self._path_type()
> if t:
> path = '%s [%s]' % (path, t)
> @@ -1621,7 +1629,7 @@ class StdPathPrinter:
>
> class _iterator(Iterator):
> def __init__(self, impl, pathtype):
> - self.pathtype = pathtype
> + self._pathtype = pathtype
> if impl:
> # We can't access _Impl::_M_size because _Impl is incomplete
> # so cast to int* to access the _M_size member at offset zero,
> @@ -1630,96 +1638,96 @@ class StdPathPrinter:
> char_type = gdb.lookup_type('char')
> impl = impl.cast(int_type.pointer())
> size = impl.dereference()
> - #self.capacity = (impl + 1).dereference()
> + #self._capacity = (impl + 1).dereference()
> if hasattr(gdb.Type, 'alignof'):
> sizeof_Impl = max(2 * int_type.sizeof, cmpt_type.alignof)
> else:
> sizeof_Impl = 2 * int_type.sizeof
> begin = impl.cast(char_type.pointer()) + sizeof_Impl
> - self.item = begin.cast(cmpt_type.pointer())
> - self.finish = self.item + size
> - self.count = 0
> + self._item = begin.cast(cmpt_type.pointer())
> + self._finish = self._item + size
> + self._count = 0
> else:
> - self.item = None
> - self.finish = None
> + self._item = None
> + self._finish = None
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.item == self.finish:
> + if self._item == self._finish:
> raise StopIteration
> - item = self.item.dereference()
> - count = self.count
> - self.count = self.count + 1
> - self.item = self.item + 1
> + item = self._item.dereference()
> + count = self._count
> + self._count = self._count + 1
> + self._item = self._item + 1
> path = item['_M_pathname']
> - t = StdPathPrinter(self.pathtype, item)._path_type()
> + t = StdPathPrinter(self._pathtype, item)._path_type()
> if not t:
> t = count
> return ('[%s]' % t, path)
>
> def children(self):
> - return self._iterator(self.impl, self.typename)
> + return self._iterator(self._impl, self._typename)
>
>
> -class StdPairPrinter:
> +class StdPairPrinter(printer_base):
> "Print a std::pair object, with 'first' and 'second' as children"
>
> def __init__(self, typename, val):
> - self.val = val
> + self._val = val
>
> class _iter(Iterator):
> "An iterator for std::pair types. Returns 'first' then 'second'."
>
> def __init__(self, val):
> - self.val = val
> - self.which = 'first'
> + self._val = val
> + self._which = 'first'
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.which is None:
> + if self._which is None:
> raise StopIteration
> - which = self.which
> + which = self._which
> if which == 'first':
> - self.which = 'second'
> + self._which = 'second'
> else:
> - self.which = None
> - return (which, self.val[which])
> + self._which = None
> + return (which, self._val[which])
>
> def children(self):
> - return self._iter(self.val)
> + return self._iter(self._val)
>
> def to_string(self):
> return None
>
>
> -class StdCmpCatPrinter:
> +class StdCmpCatPrinter(printer_base):
> "Print a comparison category object"
>
> def __init__(self, typename, val):
> - self.typename = typename[typename.rfind(':')+1:]
> - self.val = val['_M_value']
> + self._typename = typename[typename.rfind(':')+1:]
> + self._val = val['_M_value']
>
> def to_string(self):
> - if self.typename == 'strong_ordering' and self.val == 0:
> + if self._typename == 'strong_ordering' and self._val == 0:
> name = 'equal'
> else:
> names = {2: 'unordered', -1: 'less', 0: 'equivalent', 1: 'greater'}
> - name = names[int(self.val)]
> - return 'std::{}::{}'.format(self.typename, name)
> + name = names[int(self._val)]
> + return 'std::{}::{}'.format(self._typename, name)
>
>
> -class StdErrorCodePrinter:
> +class StdErrorCodePrinter(printer_base):
> "Print a std::error_code or std::error_condition"
>
> _system_is_posix = None # Whether std::system_category() use errno values.
>
> def __init__(self, typename, val):
> - self.val = val
> - self.typename = strip_versioned_namespace(typename)
> + self._val = val
> + self._typename = strip_versioned_namespace(typename)
> # Do this only once ...
> if StdErrorCodePrinter._system_is_posix is None:
> try:
> @@ -1807,14 +1815,14 @@ class StdErrorCodePrinter:
> return name.split('::')[-1]
>
> def to_string(self):
> - value = self.val['_M_value']
> - cat = self.val['_M_cat']
> + value = self._val['_M_value']
> + cat = self._val['_M_cat']
> name, alt_name, enum, is_errno = self._category_info(cat)
> if value == 0:
> default_cats = {'error_code': 'system',
> 'error_condition': 'generic'}
> - if name == default_cats[self._unqualified_name(self.typename)]:
> - return self.typename + ' = { }' # default-constructed value
> + if name == default_cats[self._unqualified_name(self._typename)]:
> + return self._typename + ' = { }' # default-constructed value
>
> strval = str(value)
> if is_errno and value != 0:
> @@ -1829,21 +1837,21 @@ class StdErrorCodePrinter:
> name = '"%s"' % name
> else:
> name = alt_name
> - return '%s = {%s: %s}' % (self.typename, name, strval)
> + return '%s = {%s: %s}' % (self._typename, name, strval)
>
>
> -class StdRegexStatePrinter:
> +class StdRegexStatePrinter(printer_base):
> "Print a state node in the NFA for a std::regex"
>
> def __init__(self, typename, val):
> - self.val = val
> - self.typename = typename
> + self._val = val
> + self._typename = typename
>
> def to_string(self):
> - opcode = str(self.val['_M_opcode'])
> + opcode = str(self._val['_M_opcode'])
> if opcode:
> opcode = opcode[25:]
> - next_id = self.val['_M_next']
> + next_id = self._val['_M_next']
>
> variants = {'repeat': 'alt', 'alternative': 'alt',
> 'subexpr_begin': 'subexpr', 'subexpr_end': 'subexpr',
> @@ -1856,113 +1864,113 @@ class StdRegexStatePrinter:
> v = variants[opcode]
>
> s = "opcode={}, next={}".format(opcode, next_id)
> - if v is not None and self.val['_M_' + v] is not None:
> - s = "{}, {}={}".format(s, v, self.val['_M_' + v])
> + if v is not None and self._val['_M_' + v] is not None:
> + s = "{}, {}={}".format(s, v, self._val['_M_' + v])
> return "{%s}" % (s)
>
>
> -class StdSpanPrinter:
> +class StdSpanPrinter(printer_base):
> "Print a std::span"
>
> - class iterator(Iterator):
> + class _iterator(Iterator):
> def __init__(self, begin, size):
> - self.count = 0
> - self.begin = begin
> - self.size = size
> + self._count = 0
> + self._begin = begin
> + self._size = size
>
> def __iter__(self):
> return self
>
> def __next__(self):
> - if self.count == self.size:
> + if self._count == self._size:
> raise StopIteration
>
> - count = self.count
> - self.count = self.count + 1
> - return '[%d]' % count, (self.begin + count).dereference()
> + count = self._count
> + self._count = self._count + 1
> + return '[%d]' % count, (self._begin + count).dereference()
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
> if val.type.template_argument(1) == gdb.parse_and_eval('static_cast<std::size_t>(-1)'):
> - self.size = val['_M_extent']['_M_extent_value']
> + self._size = val['_M_extent']['_M_extent_value']
> else:
> - self.size = val.type.template_argument(1)
> + self._size = val.type.template_argument(1)
>
> def to_string(self):
> - return '%s of length %d' % (self.typename, self.size)
> + return '%s of length %d' % (self._typename, self._size)
>
> def children(self):
> - return self.iterator(self.val['_M_ptr'], self.size)
> + return self._iterator(self._val['_M_ptr'], self._size)
>
> def display_hint(self):
> return 'array'
>
>
> -class StdInitializerListPrinter:
> +class StdInitializerListPrinter(printer_base):
> "Print a std::initializer_list"
>
> def __init__(self, typename, val):
> - self.typename = typename
> - self.val = val
> - self.size = val['_M_len']
> + self._typename = typename
> + self._val = val
> + self._size = val['_M_len']
>
> def to_string(self):
> - return '%s of length %d' % (self.typename, self.size)
> + return '%s of length %d' % (self._typename, self._size)
>
> def children(self):
> - return StdSpanPrinter.iterator(self.val['_M_array'], self.size)
> + return StdSpanPrinter._iterator(self._val['_M_array'], self._size)
>
> def display_hint(self):
> return 'array'
>
>
> -class StdAtomicPrinter:
> +class StdAtomicPrinter(printer_base):
> "Print a std:atomic"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> - self.shptr_printer = None
> - self.value_type = self.val.type.template_argument(0)
> - if self.value_type.tag is not None:
> - typ = strip_versioned_namespace(self.value_type.tag)
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
> + self._shptr_printer = None
> + self._value_type = self._val.type.template_argument(0)
> + if self._value_type.tag is not None:
> + typ = strip_versioned_namespace(self._value_type.tag)
> if typ.startswith('std::shared_ptr<') or typ.startswith('std::weak_ptr<'):
> impl = val['_M_impl']
> - self.shptr_printer = SharedPointerPrinter(typename, impl)
> + self._shptr_printer = SharedPointerPrinter(typename, impl)
> self.children = self._shptr_children
>
> def _shptr_children(self):
> - return SmartPtrIterator(self.shptr_printer.pointer)
> + return SmartPtrIterator(self._shptr_printer._pointer)
>
> def to_string(self):
> - if self.shptr_printer is not None:
> - return self.shptr_printer.to_string()
> -
> - if self.value_type.code == gdb.TYPE_CODE_INT:
> - val = self.val['_M_i']
> - elif self.value_type.code == gdb.TYPE_CODE_FLT:
> - val = self.val['_M_fp']
> - elif self.value_type.code == gdb.TYPE_CODE_PTR:
> - val = self.val['_M_b']['_M_p']
> - elif self.value_type.code == gdb.TYPE_CODE_BOOL:
> - val = self.val['_M_base']['_M_i']
> + if self._shptr_printer is not None:
> + return self._shptr_printer.to_string()
> +
> + if self._value_type.code == gdb.TYPE_CODE_INT:
> + val = self._val['_M_i']
> + elif self._value_type.code == gdb.TYPE_CODE_FLT:
> + val = self._val['_M_fp']
> + elif self._value_type.code == gdb.TYPE_CODE_PTR:
> + val = self._val['_M_b']['_M_p']
> + elif self._value_type.code == gdb.TYPE_CODE_BOOL:
> + val = self._val['_M_base']['_M_i']
> else:
> - val = self.val['_M_i']
> - return '%s<%s> = { %s }' % (self.typename, str(self.value_type), val)
> + val = self._val['_M_i']
> + return '%s<%s> = { %s }' % (self._typename, str(self._value_type), val)
>
>
> -class StdFormatArgsPrinter:
> +class StdFormatArgsPrinter(printer_base):
> "Print a std::basic_format_args"
> # TODO: add printer for basic_format_arg<Context> and print out children.
> # TODO: add printer for __format::_ArgStore<Context, Args...>.
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def to_string(self):
> - targs = get_template_arg_list(self.val.type)
> + targs = get_template_arg_list(self._val.type)
> char_type = get_template_arg_list(targs[0])[1]
> if char_type == gdb.lookup_type('char'):
> typ = 'std::format_args'
> @@ -1971,32 +1979,32 @@ class StdFormatArgsPrinter:
> else:
> typ = 'std::basic_format_args'
>
> - size = self.val['_M_packed_size']
> + size = self._val['_M_packed_size']
> if size == 1:
> return "%s with 1 argument" % (typ)
> if size == 0:
> - size = self.val['_M_unpacked_size']
> + size = self._val['_M_unpacked_size']
> return "%s with %d arguments" % (typ, size)
>
>
> def std_ratio_t_tuple(ratio_type):
> # TODO use reduced period i.e. duration::period
> - period = self.val.type.template_argument(1)
> + period = self._val.type.template_argument(1)
> num = period.template_argument(0)
> den = period.template_argument(1)
> return (num, den)
>
>
> -class StdChronoDurationPrinter:
> +class StdChronoDurationPrinter(printer_base):
> "Print a std::chrono::duration"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def _ratio(self):
> # TODO use reduced period i.e. duration::period
> - period = self.val.type.template_argument(1)
> + period = self._val.type.template_argument(1)
> num = period.template_argument(0)
> den = period.template_argument(1)
> return (num, den)
> @@ -2023,21 +2031,21 @@ class StdChronoDurationPrinter:
> return "[{}/{}]s".format(num, den)
>
> def to_string(self):
> - r = self.val['__r']
> + r = self._val['__r']
> if r.type.strip_typedefs().code == gdb.TYPE_CODE_FLT:
> r = "%g" % r
> return "std::chrono::duration = {{ {}{} }}".format(r, self._suffix())
>
>
> -class StdChronoTimePointPrinter:
> +class StdChronoTimePointPrinter(printer_base):
> "Print a std::chrono::time_point"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def _clock(self):
> - clock = self.val.type.template_argument(0)
> + clock = self._val.type.template_argument(0)
> name = strip_versioned_namespace(clock.name)
> if name == 'std::chrono::_V2::system_clock' \
> or name == 'std::chrono::system_clock':
> @@ -2057,7 +2065,7 @@ class StdChronoTimePointPrinter:
>
> def to_string(self, abbrev=False):
> clock, offset = self._clock()
> - d = self.val['__d']
> + d = self._val['__d']
> r = d['__r']
> printer = StdChronoDurationPrinter(d.type.name, d)
> suffix = printer._suffix()
> @@ -2076,16 +2084,16 @@ class StdChronoTimePointPrinter:
> return '%s = { %s }' % (clock, s)
>
>
> -class StdChronoZonedTimePrinter:
> +class StdChronoZonedTimePrinter(printer_base):
> "Print a std::chrono::zoned_time"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def to_string(self):
> - zone = self.val['_M_zone'].dereference()['_M_name']
> - time = self.val['_M_tp']
> + zone = self._val['_M_zone'].dereference()['_M_name']
> + time = self._val['_M_tp']
> printer = StdChronoTimePointPrinter(time.type.name, time)
> time = printer.to_string(True)
> return 'std::chrono::zoned_time = {{ {} {} }}'.format(zone, time)
> @@ -2098,16 +2106,16 @@ weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
> 'Saturday', 'Sunday']
>
>
> -class StdChronoCalendarPrinter:
> +class StdChronoCalendarPrinter(printer_base):
> "Print a std::chrono::day, std::chrono::month, std::chrono::year etc."
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def to_string(self):
> - val = self.val
> - typ = self.typename
> + val = self._val
> + typ = self._typename
> if 'month' in typ and typ != 'std::chrono::year_month_day_last':
> m = val['_M_m']
> if typ.startswith('std::chrono::year'):
> @@ -2161,53 +2169,53 @@ class StdChronoCalendarPrinter:
> return '{:02}:{:02}:{:02}{}'.format(h, m, s, fract)
>
>
> -class StdChronoTimeZonePrinter:
> +class StdChronoTimeZonePrinter(printer_base):
> "Print a chrono::time_zone or chrono::time_zone_link"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def to_string(self):
> - str = '%s = %s' % (self.typename, self.val['_M_name'])
> - if self.typename.endswith("_link"):
> - str += ' -> %s' % (self.val['_M_target'])
> + str = '%s = %s' % (self._typename, self._val['_M_name'])
> + if self._typename.endswith("_link"):
> + str += ' -> %s' % (self._val['_M_target'])
> return str
>
>
> -class StdChronoLeapSecondPrinter:
> +class StdChronoLeapSecondPrinter(printer_base):
> "Print a chrono::leap_second"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def to_string(self):
> - date = self.val['_M_s']['__r']
> + date = self._val['_M_s']['__r']
> neg = '+-'[date < 0]
> - return '%s %d (%c)' % (self.typename, abs(date), neg)
> + return '%s %d (%c)' % (self._typename, abs(date), neg)
>
>
> -class StdChronoTzdbPrinter:
> +class StdChronoTzdbPrinter(printer_base):
> "Print a chrono::tzdb"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def to_string(self):
> - return '%s %s' % (self.typename, self.val['version'])
> + return '%s %s' % (self._typename, self._val['version'])
>
>
> -class StdChronoTimeZoneRulePrinter:
> +class StdChronoTimeZoneRulePrinter(printer_base):
> "Print a chrono::time_zone rule"
>
> def __init__(self, typename, val):
> - self.typename = strip_versioned_namespace(typename)
> - self.val = val
> + self._typename = strip_versioned_namespace(typename)
> + self._val = val
>
> def to_string(self):
> - on = self.val['on']
> + on = self._val['on']
> kind = on['kind']
> month = months[on['month']]
> suffixes = {1: 'st', 2: 'nd', 3: 'rd',
> @@ -2230,24 +2238,24 @@ class StdChronoTimeZoneRulePrinter:
> direction[1], month,
> ordinal_day)
> return 'time_zone rule {} from {} to {} starting on {}'.format(
> - self.val['name'], self.val['from'], self.val['to'], start)
> + self._val['name'], self._val['from'], self._val['to'], start)
>
>
> -class StdLocalePrinter:
> +class StdLocalePrinter(printer_base):
> "Print a std::locale"
>
> def __init__(self, typename, val):
> - self.val = val
> - self.typename = typename
> + self._val = val
> + self._typename = typename
>
> def to_string(self):
> - names = self.val['_M_impl']['_M_names']
> + names = self._val['_M_impl']['_M_names']
> mod = ''
> if names[0] == 0:
> name = '*'
> else:
> - cats = gdb.parse_and_eval(self.typename + '::_S_categories')
> - ncat = gdb.parse_and_eval(self.typename + '::_S_categories_size')
> + cats = gdb.parse_and_eval(self._typename + '::_S_categories')
> + ncat = gdb.parse_and_eval(self._typename + '::_S_categories_size')
> n = names[0].string()
> cat = cats[0].string()
> name = '{}={}'.format(cat, n)
> @@ -2284,7 +2292,7 @@ class RxPrinter(object):
> def __init__(self, name, function):
> super(RxPrinter, self).__init__()
> self.name = name
> - self.function = function
> + self._function = function
> self.enabled = True
>
> def invoke(self, value):
> @@ -2295,7 +2303,7 @@ class RxPrinter(object):
> if hasattr(gdb.Value, "referenced_value"):
> value = value.referenced_value()
>
> - return self.function(self.name, value)
> + return self._function(self.name, value)
>
> # A pretty-printer that conforms to the "PrettyPrinter" protocol from
> # gdb.printing. It can also be used directly as an old-style printer.
> @@ -2305,20 +2313,20 @@ class Printer(object):
> def __init__(self, name):
> super(Printer, self).__init__()
> self.name = name
> - self.subprinters = []
> - self.lookup = {}
> + self._subprinters = []
> + self._lookup = {}
> self.enabled = True
> - self.compiled_rx = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$')
> + self._compiled_rx = re.compile('^([a-zA-Z0-9_:]+)(<.*>)?$')
>
> def add(self, name, function):
> # A small sanity check.
> # FIXME
> - if not self.compiled_rx.match(name):
> + if not self._compiled_rx.match(name):
> raise ValueError(
> 'libstdc++ programming error: "%s" does not match' % name)
> printer = RxPrinter(name, function)
> - self.subprinters.append(printer)
> - self.lookup[name] = printer
> + self._subprinters.append(printer)
> + self._lookup[name] = printer
>
> # Add a name using _GLIBCXX_BEGIN_NAMESPACE_VERSION.
> def add_version(self, base, name, function):
> @@ -2351,7 +2359,7 @@ class Printer(object):
>
> # All the types we match are template types, so we can use a
> # dictionary.
> - match = self.compiled_rx.match(typename)
> + match = self._compiled_rx.match(typename)
> if not match:
> return None
>
> @@ -2361,8 +2369,8 @@ class Printer(object):
> if hasattr(gdb.Value, "referenced_value"):
> val = val.referenced_value()
>
> - if basename in self.lookup:
> - return self.lookup[basename].invoke(val)
> + if basename in self._lookup:
> + return self._lookup[basename].invoke(val)
>
> # Cannot find a pretty printer. Return None.
> return None
> @@ -2384,7 +2392,7 @@ class TemplateTypePrinter(object):
>
> def __init__(self, name, defargs):
> self.name = name
> - self.defargs = defargs
> + self._defargs = defargs
> self.enabled = True
>
> class _recognizer(object):
> @@ -2392,8 +2400,8 @@ class TemplateTypePrinter(object):
>
> def __init__(self, name, defargs):
> self.name = name
> - self.defargs = defargs
> - # self.type_obj = None
> + self._defargs = defargs
> + # self._type_obj = None
>
> def recognize(self, type_obj):
> """
> @@ -2416,7 +2424,7 @@ class TemplateTypePrinter(object):
> # The actual template argument in the type:
> targ = template_args[n]
> # The default template argument for the class template:
> - defarg = self.defargs.get(n)
> + defarg = self._defargs.get(n)
> if defarg is not None:
> # Substitute other template arguments into the default:
> defarg = defarg.format(*template_args)
> @@ -2469,7 +2477,7 @@ class TemplateTypePrinter(object):
>
> def instantiate(self):
> "Return a recognizer object for this type printer."
> - return self._recognizer(self.name, self.defargs)
> + return self._recognizer(self.name, self._defargs)
>
>
> def add_one_template_type_printer(obj, name, defargs):
> @@ -2533,58 +2541,59 @@ class FilteringTypePrinter(object):
> """
>
> def __init__(self, template, name, targ1=None):
> - self.template = template
> + self._template = template
> self.name = name
> - self.targ1 = targ1
> + self._targ1 = targ1
> self.enabled = True
>
> class _recognizer(object):
> "The recognizer class for FilteringTypePrinter."
>
> def __init__(self, template, name, targ1):
> - self.template = template
> + self._template = template
> self.name = name
> - self.targ1 = targ1
> - self.type_obj = None
> + self._targ1 = targ1
> + self._type_obj = None
>
> def recognize(self, type_obj):
> """
> - If type_obj starts with self.template and is the same type as
> + If type_obj starts with self._template and is the same type as
> self.name then return self.name, otherwise None.
> """
> if type_obj.tag is None:
> return None
>
> - if self.type_obj is None:
> - if self.targ1 is not None:
> - if not type_obj.tag.startswith('{}<{}'.format(self.template, self.targ1)):
> + if self._type_obj is None:
> + if self._targ1 is not None:
> + if not type_obj.tag.startswith('{}<{}'.format(self._template, self._targ1)):
> # Filter didn't match.
> return None
> - elif not type_obj.tag.startswith(self.template):
> + elif not type_obj.tag.startswith(self._template):
> # Filter didn't match.
> return None
>
> try:
> - self.type_obj = gdb.lookup_type(self.name).strip_typedefs()
> + self._type_obj = gdb.lookup_type(
> + self.name).strip_typedefs()
> except:
> pass
>
> - if self.type_obj is None:
> + if self._type_obj is None:
> return None
>
> - if gdb.types.get_basic_type(self.type_obj) == gdb.types.get_basic_type(type_obj):
> + if gdb.types.get_basic_type(self._type_obj) == gdb.types.get_basic_type(type_obj):
> return strip_inline_namespaces(self.name)
>
> # Workaround ambiguous typedefs matching both std:: and std::__cxx11:: symbols.
> - if self.template.split('::')[-1] == 'basic_string':
> - if self.type_obj.tag.replace('__cxx11::', '') == type_obj.tag.replace('__cxx11::', ''):
> + if self._template.split('::')[-1] == 'basic_string':
> + if self._type_obj.tag.replace('__cxx11::', '') == type_obj.tag.replace('__cxx11::', ''):
> return strip_inline_namespaces(self.name)
>
> return None
>
> def instantiate(self):
> "Return a recognizer object for this type printer."
> - return self._recognizer(self.template, self.name, self.targ1)
> + return self._recognizer(self._template, self.name, self._targ1)
>
>
> def add_one_type_printer(obj, template, name, targ1=None):
> --
> 2.40.1
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class
2023-09-28 20:26 ` Jonathan Wakely
@ 2023-09-28 20:38 ` Tom Tromey
2023-09-28 20:49 ` Jonathan Wakely
0 siblings, 1 reply; 18+ messages in thread
From: Tom Tromey @ 2023-09-28 20:38 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: Tom Tromey, gcc-patches, libstdc++
Jonathan> I've pushed the changes I wanted to make, so you'll have to rebase
Jonathan> your patches now, sorry.
No problem. I rebased & re-tested them.
I can send a v2 if you want to double-check (only this large patch
required any changes), or just go ahead. Let me know.
I may not be able to push until Monday.
Tom
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class
2023-09-28 20:38 ` Tom Tromey
@ 2023-09-28 20:49 ` Jonathan Wakely
0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Wakely @ 2023-09-28 20:49 UTC (permalink / raw)
To: Tom Tromey; +Cc: gcc-patches, libstdc++
[-- Attachment #1: Type: text/plain, Size: 509 bytes --]
On Thu, 28 Sept 2023, 21:38 Tom Tromey, <tromey@adacore.com> wrote:
> Jonathan> I've pushed the changes I wanted to make, so you'll have to
> rebase
> Jonathan> your patches now, sorry.
>
> No problem. I rebased & re-tested them.
> I can send a v2 if you want to double-check (only this large patch
> required any changes), or just go ahead. Let me know.
>
Just go ahead, the changes are all straightforward so if the tests still
pass, you can push it.
I may not be able to push until Monday.
>
> Tom
>
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2023-09-28 20:50 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-28 17:46 [PATCH 0/7] libstdc++: Use gdb.ValuePrinter in pretty-printers Tom Tromey
2023-09-28 17:46 ` [PATCH 1/7] libstdc++: Show full Python stack on error Tom Tromey
2023-09-28 18:49 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 2/7] libstdc++: Use gdb.ValuePrinter base class Tom Tromey
2023-09-28 20:26 ` Jonathan Wakely
2023-09-28 20:38 ` Tom Tromey
2023-09-28 20:49 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 3/7] libstdc++: Remove unused Python imports Tom Tromey
2023-09-28 18:53 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 4/7] libstdc++: Remove unused locals from printers.py Tom Tromey
2023-09-28 18:53 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 5/7] libstdc++: Remove std_ratio_t_tuple Tom Tromey
2023-09-28 19:01 ` Jonathan Wakely
2023-09-28 17:46 ` [PATCH 6/7] libstdc++: Fix regex escapes in pretty-printers Tom Tromey
2023-09-28 18:51 ` Jonathan Wakely
2023-09-28 19:11 ` Tom Tromey
2023-09-28 17:46 ` [PATCH 7/7] libstdc++: Use Python "not in" operator Tom Tromey
2023-09-28 18:52 ` Jonathan Wakely
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).