From patchwork Fri Jul 11 02:48:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Bronson X-Patchwork-Id: 2005 Received: (qmail 13198 invoked by alias); 11 Jul 2014 03:22:41 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 8398 invoked by uid 89); 11 Jul 2014 03:18:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qa0-f42.google.com Received: from mail-qa0-f42.google.com (HELO mail-qa0-f42.google.com) (209.85.216.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Fri, 11 Jul 2014 03:18:18 +0000 Received: by mail-qa0-f42.google.com with SMTP id j15so422638qaq.15 for ; Thu, 10 Jul 2014 20:18:16 -0700 (PDT) X-Received: by 10.224.22.12 with SMTP id l12mr89757004qab.88.1405048696235; Thu, 10 Jul 2014 20:18:16 -0700 (PDT) Received: from hydrogen (naesten-pt.tunnel.tserv4.nyc4.ipv6.he.net. [2001:470:1f06:57::2]) by mx.google.com with ESMTPSA id 97sm1114051qgl.45.2014.07.10.20.18.13 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Thu, 10 Jul 2014 20:18:14 -0700 (PDT) Received: from naesten by hydrogen with local (Exim 4.82) (envelope-from ) id 1X5RLg-0000Bz-Jp; Thu, 10 Jul 2014 23:18:12 -0400 From: Samuel Bronson To: libstdc++@gcc.gnu.org, GCC Patches Cc: Samuel Bronson , Jonathan Wakely , GDB Patches , Tom Tromey , Mathias Klose Subject: [PATCH v2 3/3] Port libstdc++ pretty-printers to Python 2 + Python 3 Date: Thu, 10 Jul 2014 22:48:19 -0400 Message-Id: <1405046899-32639-4-git-send-email-naesten@gmail.com> In-Reply-To: <1405046899-32639-1-git-send-email-naesten@gmail.com> References: <1400701554-18062-1-git-send-email-naesten@gmail.com> <1405046899-32639-1-git-send-email-naesten@gmail.com> MIME-Version: 1.0 X-IsSubscribed: yes Loosely based on Mathias Klose' earlier patch . Tested with: $ make check-target-libstdc++-v3 RUNTESTFLAGS='--directory libstdc++-prettyprinters' libstdc++-v3/ PR libstdc++/58962 * python/libstdcxx/v6/printers.py: Port to Python 2+3 (imap): New compat function. (izip): Likewise. (Iterator): New mixin to allow writing iterators in Python 3 style regardless of which version we're running on. [Python3] (long) New compat alias for "int". * testsuite/lib/gdb-test.exp: Port to Python 2+3 (print syntax) Signed-off-by: Mathias Klose Signed-off-by: Samuel Bronson --- libstdc++-v3/python/libstdcxx/v6/printers.py | 110 +++++++++++++++++++-------- libstdc++-v3/testsuite/lib/gdb-test.exp | 4 +- 2 files changed, 79 insertions(+), 35 deletions(-) diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py index 623a815..313b08d 100644 --- a/libstdc++-v3/python/libstdcxx/v6/printers.py +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py @@ -1,4 +1,4 @@ -# Pretty-printers for libstc++. +# Pretty-printers for libstdc++. # Copyright (C) 2008-2014 Free Software Foundation, Inc. @@ -18,6 +18,50 @@ import gdb import itertools import re +import sys + +### Python 2 + Python 3 compatability code + +# Resources about compatability: +# +# * : Documentation of the "six" module + +# FIXME: The handling of e.g. std::basic_string (at least on char) +# probably needs updating to work with Python 3's new string rules. +# +# In particular, Python 3 has a separate type (called byte) for +# bytestrings, and a special b"" syntax for the byte literals; the old +# str() type has been redefined to always store Unicode text. +# +# We probably can't do much about this until GDB get their act +# together: + +if sys.version_info[0] > 2: + ### Python 3 stuff + Iterator = object + # Python 3 folds these into the normal functions. + imap = map + izip = zip + # Also, int subsumes long + long = int +else: + ### Python 2 stuff + class Iterator: + """Compatability mixin for iterators + + Instead of writing next() methods for iterators, write + __next__() methods and use this mixin to make them work in + Python 2 as well as Python 3. + + Idea stolen from the "six" documentation: + + """ + + def next(self): + return self.__next__() + + # In Python 2, we still need these from itertools + from itertools import imap, izip # Try to use the new-style pretty-printing if available. _use_gdb_pp = True @@ -87,7 +131,7 @@ class UniquePointerPrinter: class StdListPrinter: "Print a std::list" - class _iterator: + class _iterator(Iterator): def __init__(self, nodetype, head): self.nodetype = nodetype self.base = head['_M_next'] @@ -97,7 +141,7 @@ class StdListPrinter: def __iter__(self): return self - def next(self): + def __next__(self): if self.base == self.head: raise StopIteration elt = self.base.cast(self.nodetype).dereference() @@ -135,7 +179,7 @@ class StdListIteratorPrinter: class StdSlistPrinter: "Print a __gnu_cxx::slist" - class _iterator: + class _iterator(Iterator): def __init__(self, nodetype, head): self.nodetype = nodetype self.base = head['_M_head']['_M_next'] @@ -144,7 +188,7 @@ class StdSlistPrinter: def __iter__(self): return self - def next(self): + def __next__(self): if self.base == 0: raise StopIteration elt = self.base.cast(self.nodetype).dereference() @@ -180,7 +224,7 @@ class StdSlistIteratorPrinter: class StdVectorPrinter: "Print a std::vector" - class _iterator: + class _iterator(Iterator): def __init__ (self, start, finish, bitvec): self.bitvec = bitvec if bitvec: @@ -198,7 +242,7 @@ class StdVectorPrinter: def __iter__(self): return self - def next(self): + def __next__(self): count = self.count self.count = self.count + 1 if self.bitvec: @@ -265,7 +309,7 @@ class StdVectorIteratorPrinter: class StdTuplePrinter: "Print a std::tuple" - class _iterator: + class _iterator(Iterator): def __init__ (self, head): self.head = head @@ -282,7 +326,7 @@ class StdTuplePrinter: def __iter__ (self): return self - def next (self): + def __next__ (self): nodes = self.head.type.fields () # Check for further recursions in the inheritance tree. if len (nodes) == 0: @@ -341,7 +385,7 @@ class StdStackOrQueuePrinter: return self.visualizer.display_hint () return None -class RbtreeIterator: +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'] @@ -353,7 +397,7 @@ class RbtreeIterator: def __len__(self): return int (self.size) - def next(self): + def __next__(self): if self.count == self.size: raise StopIteration result = self.node @@ -422,7 +466,7 @@ class StdMapPrinter: "Print a std::map or std::multimap" # Turn an RbtreeIterator into a pretty-print iterator. - class _iter: + class _iter(Iterator): def __init__(self, rbiter, type): self.rbiter = rbiter self.count = 0 @@ -431,9 +475,9 @@ class StdMapPrinter: def __iter__(self): return self - def next(self): + def __next__(self): if self.count % 2 == 0: - n = self.rbiter.next() + n = next(self.rbiter) n = n.cast(self.type).dereference() n = get_value_from_Rb_tree_node(n) self.pair = n @@ -465,7 +509,7 @@ class StdSetPrinter: "Print a std::set or std::multiset" # Turn an RbtreeIterator into a pretty-print iterator. - class _iter: + class _iter(Iterator): def __init__(self, rbiter, type): self.rbiter = rbiter self.count = 0 @@ -474,8 +518,8 @@ class StdSetPrinter: def __iter__(self): return self - def next(self): - item = self.rbiter.next() + def __next__(self): + 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? @@ -541,7 +585,7 @@ class StdBitsetPrinter: class StdDequePrinter: "Print a std::deque" - class _iter: + class _iter(Iterator): def __init__(self, node, start, end, last, buffer_size): self.node = node self.p = start @@ -553,7 +597,7 @@ class StdDequePrinter: def __iter__(self): return self - def next(self): + def __next__(self): if self.p == self.last: raise StopIteration @@ -638,7 +682,7 @@ class StdStringPrinter: def display_hint (self): return 'string' -class Tr1HashtableIterator: +class Tr1HashtableIterator(Iterator): def __init__ (self, hash): self.buckets = hash['_M_buckets'] self.bucket = 0 @@ -654,7 +698,7 @@ class Tr1HashtableIterator: def __iter__ (self): return self - def next (self): + def __next__ (self): if self.node == 0: raise StopIteration node = self.node.cast(self.node_type) @@ -669,7 +713,7 @@ class Tr1HashtableIterator: self.bucket = self.bucket + 1 return result -class StdHashtableIterator: +class StdHashtableIterator(Iterator): def __init__(self, hash): self.node = hash['_M_before_begin']['_M_nxt'] self.node_type = find_type(hash.type, '__node_type').pointer() @@ -677,7 +721,7 @@ class StdHashtableIterator: def __iter__(self): return self - def next(self): + def __next__(self): if self.node == 0: raise StopIteration elt = self.node.cast(self.node_type).dereference() @@ -706,10 +750,10 @@ class Tr1UnorderedSetPrinter: return '[%d]' % i def children (self): - counter = itertools.imap (self.format_count, itertools.count()) + counter = imap (self.format_count, itertools.count()) if self.typename.startswith('std::tr1'): - return itertools.izip (counter, Tr1HashtableIterator (self.hashtable())) - return itertools.izip (counter, StdHashtableIterator (self.hashtable())) + return izip (counter, Tr1HashtableIterator (self.hashtable())) + return izip (counter, StdHashtableIterator (self.hashtable())) class Tr1UnorderedMapPrinter: "Print a tr1::unordered_map" @@ -741,15 +785,15 @@ class Tr1UnorderedMapPrinter: return '[%d]' % i def children (self): - counter = itertools.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 (itertools.imap (self.format_one, Tr1HashtableIterator (self.hashtable()))) + data = self.flatten (imap (self.format_one, Tr1HashtableIterator (self.hashtable()))) # Zip the two iterators together. - return itertools.izip (counter, data) - data = self.flatten (itertools.imap (self.format_one, StdHashtableIterator (self.hashtable()))) + return izip (counter, data) + data = self.flatten (imap (self.format_one, StdHashtableIterator (self.hashtable()))) # Zip the two iterators together. - return itertools.izip (counter, data) + return izip (counter, data) def display_hint (self): @@ -758,7 +802,7 @@ class Tr1UnorderedMapPrinter: class StdForwardListPrinter: "Print a std::forward_list" - class _iterator: + class _iterator(Iterator): def __init__(self, nodetype, head): self.nodetype = nodetype self.base = head['_M_next'] @@ -767,7 +811,7 @@ class StdForwardListPrinter: def __iter__(self): return self - def next(self): + def __next__(self): if self.base == 0: raise StopIteration elt = self.base.cast(self.nodetype).dereference() diff --git a/libstdc++-v3/testsuite/lib/gdb-test.exp b/libstdc++-v3/testsuite/lib/gdb-test.exp index 6d7ea9d..9cb6ecf 100644 --- a/libstdc++-v3/testsuite/lib/gdb-test.exp +++ b/libstdc++-v3/testsuite/lib/gdb-test.exp @@ -91,7 +91,7 @@ proc gdb-test { marker {selector {}} } { } } - set do_whatis_tests [gdb_batch_check "python print gdb.type_printers" \ + set do_whatis_tests [gdb_batch_check "python print(gdb.type_printers)" \ "\\\[\\\]"] if {!$do_whatis_tests} { send_log "skipping 'whatis' tests - gdb too old" @@ -259,6 +259,6 @@ proc gdb_batch_check {command pattern} { # but not earlier versions. # Return 1 if the version is ok, 0 otherwise. proc gdb_version_check {} { - return [gdb_batch_check "python print gdb.lookup_global_symbol" \ + return [gdb_batch_check "python print(gdb.lookup_global_symbol)" \ ""] }