* [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
* 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
* [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
* 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
* [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
* 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
* [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
* 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
* [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
* 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
* [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
* 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 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
* [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 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
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).