Home | History | Annotate | Download | only in stlport
      1 # GDB pretty printers for STLport.
      2 #
      3 # Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
      4 # Copyright (C) 2010 Joachim Reichel
      5 #
      6 # This program is free software; you can redistribute it and/or modify
      7 # it under the terms of the GNU General Public License as published by
      8 # the Free Software Foundation; either version 3 of the License, or
      9 # (at your option) any later version.
     10 #
     11 # This program is distributed in the hope that it will be useful,
     12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 # GNU General Public License for more details.
     15 #
     16 # You should have received a copy of the GNU General Public License
     17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     18 
     19 
     20 # pylint: disable=C0103,C0111,R0201,R0903
     21 
     22 
     23 import gdb
     24 import re
     25 
     26 
     27 # Set the STLport version which is needed for a few features.
     28 #
     29 # - for std::list:
     30 #   STLport older than 5.0?
     31 # - for std::deque, std::stack, and std::queue on 64bit systems:
     32 #   STLport older than 5.2?
     33 stlport_version = 5.2
     34 
     35 # Indicates whether std::vector is printed with indices.
     36 print_vector_with_indices = False
     37 
     38 
     39 def lookup_stlport_type (typename):
     40     "Look up a type in the public STLport namespace."
     41 
     42     namespaces = ['std::', 'stlpd_std::', 'stlp_std::', '_STL::']
     43     for namespace in namespaces:
     44         try:
     45             return gdb.lookup_type (namespace + typename)
     46         except RuntimeError:
     47             pass
     48 
     49 def lookup_stlport_priv_type (typename):
     50     "Look up a type in the private STLport namespace."
     51 
     52     namespaces = ['std::priv::', 'stlpd_std::priv::', 'stlp_priv::', 'stlp_std::priv::',
     53                   'stlpd_std::', 'stlp_std::', '_STL::']
     54     for namespace in namespaces:
     55         try:
     56             return gdb.lookup_type (namespace + typename)
     57         except RuntimeError:
     58             pass
     59 
     60 
     61 def get_non_debug_impl (value, member = None):
     62     "Return the non-debug implementation of value or value[member]."
     63     if member:
     64         value = value[member]
     65     try:
     66         return value['_M_non_dbg_impl']
     67     except RuntimeError:
     68         return value
     69 
     70 
     71 class RbtreeIterator:
     72 
     73     def __init__ (self, rbtree):
     74         tree = get_non_debug_impl (rbtree , '_M_t')
     75         self.size = tree['_M_node_count']
     76         self.node = tree['_M_header']['_M_data']['_M_left']
     77         self.count = 0
     78 
     79     def __iter__ (self):
     80         return self
     81 
     82     def __len__ (self):
     83         return int (self.size)
     84 
     85     def next (self):
     86         if self.count == self.size:
     87             raise StopIteration
     88         result = self.node
     89         self.count += 1
     90         if self.count < self.size:
     91             node = self.node
     92             # Is there a right child?
     93             if node.dereference()['_M_right']:
     94                 # Walk down to left-most child in right subtree.
     95                 node = node.dereference()['_M_right']
     96                 while node.dereference()['_M_left']:
     97                     node = node.dereference()['_M_left']
     98             else:
     99                 # Walk up to first parent reached via left subtree.
    100                 parent = node.dereference()['_M_parent']
    101                 while node == parent.dereference()['_M_right']:
    102                     node = parent
    103                     parent = parent.dereference()['_M_parent']
    104                 node = parent
    105             self.node = node
    106         return result
    107 
    108 
    109 class BitsetPrinter:
    110     "Pretty printer for std::bitset."
    111 
    112     def __init__(self, typename, val):
    113         self.typename = typename
    114         self.val      = val
    115 
    116     def to_string (self):
    117         # If template_argument handled values, we could print the
    118         # size.  Or we could use a regexp on the type.
    119         return '%s' % (self.typename)
    120 
    121     def children (self):
    122         words = self.val['_M_w']
    123 
    124         # The _M_w member can be either an unsigned long, or an
    125         # array.  This depends on the template specialization used.
    126         # If it is a single long, convert to a single element list.
    127         if words.type.code == gdb.TYPE_CODE_ARRAY:
    128             word_size = words.type.target ().sizeof
    129             n_words   = words.type.sizeof / word_size
    130         else:
    131             word_size = words.type.sizeof 
    132             n_words   = 1
    133             words     = [words]
    134 
    135         result = []
    136         word = 0
    137         while word < n_words:
    138             w = words[word]
    139             bit = 0
    140             while w != 0:
    141                 if w & 1:
    142                     result.append (('[%d]' % (word * word_size * 8 + bit), 1))
    143                 bit += 1
    144                 w = w >> 1
    145             word += 1
    146         return result
    147 
    148 
    149 class DequePrinter:
    150     "Pretty printer for std::deque."
    151 
    152     class Iterator:
    153         def __init__ (self, start_node, start_cur, start_last,
    154                       finish_cur, buffer_size):
    155             self.node        = start_node
    156             self.item        = start_cur
    157             self.node_last   = start_last
    158             self.last        = finish_cur
    159             self.buffer_size = buffer_size
    160             self.count       = 0
    161 
    162         def __iter__ (self):
    163             return self
    164 
    165         def next (self):
    166             if self.item == self.last:
    167                 raise StopIteration
    168             result = ('[%d]' % self.count, self.item.dereference())
    169             self.count += 1
    170             self.item  += 1
    171             if self.item == self.node_last:
    172                 self.node += 1
    173                 self.item = self.node[0]
    174                 self.node_last = self.item + self.buffer_size
    175             return result
    176 
    177     def __init__ (self, typename, val):
    178         self.typename = typename
    179         self.val = get_non_debug_impl (val)
    180         size = val.type.template_argument(0).sizeof
    181         # see MAX_BYTES in stlport/stl/_alloc.h
    182         if stlport_version < 5.2:
    183             blocksize = 128
    184         else:
    185             blocksize = 32 * gdb.lookup_type ("void").pointer().sizeof
    186         if size < blocksize:
    187             self.buffer_size = int (blocksize / size)
    188         else:
    189             self.buffer_size = 1
    190 
    191     def to_string (self):
    192         start   = self.val['_M_start']
    193         finish  = self.val['_M_finish']
    194         delta_n = finish['_M_node'] - start['_M_node'] - 1
    195         delta_s = start['_M_last'] - start['_M_cur']
    196         delta_f = finish['_M_cur'] - finish['_M_first']
    197         if delta_n == -1:
    198             size = delta_f
    199         else:
    200             size = self.buffer_size * delta_n + delta_s + delta_f
    201         ta0 = self.val.type.template_argument (0)
    202         return '%s<%s> with %d elements' % (self.typename, ta0, int (size))
    203 
    204     def children (self):
    205         start  = self.val['_M_start']
    206         finish = self.val['_M_finish']
    207         return self.Iterator (start['_M_node'], start['_M_cur'],
    208             start['_M_last'], finish['_M_cur'], self.buffer_size)
    209 
    210     def display_hint (self):
    211         return 'array'
    212 
    213 
    214 class ListPrinter:
    215     "Pretty printer for std::list."
    216 
    217     class Iterator:
    218         def __init__ (self, node_type, head):
    219             self.node_type = node_type
    220             # see empty() in stlport/stl/_list.h
    221             if stlport_version < 5.0:
    222                 self.sentinel = head
    223             else:
    224                 self.sentinel = head.address
    225             self.item  = head['_M_next']
    226             self.count = 0
    227 
    228         def __iter__ (self):
    229             return self
    230 
    231         def next (self):
    232             if self.item == self.sentinel:
    233                 raise StopIteration
    234             node = self.item.cast (self.node_type).dereference()
    235             self.item = node['_M_next']
    236             count = self.count
    237             self.count += 1
    238             return ('[%d]' % count, node['_M_data'])
    239 
    240     def __init__(self, typename, val):
    241         self.typename = typename
    242         self.val = get_non_debug_impl (val)
    243 
    244     def children (self):
    245         ta0       = self.val.type.template_argument(0)
    246         node_type = lookup_stlport_priv_type ('_List_node<%s>' % ta0).pointer()
    247         return self.Iterator (node_type, self.val['_M_node']['_M_data'])
    248 
    249     def to_string (self):
    250         ta0 = self.val.type.template_argument (0)
    251         # see empty() in stlport/stl/_list.h
    252         if stlport_version < 5.0:
    253             sentinel = self.val['_M_node']['_M_data']
    254         else:
    255             sentinel = self.val['_M_node']['_M_data'].address
    256         if self.val['_M_node']['_M_data']['_M_next'] == sentinel:
    257             return 'empty %s<%s>' % (self.typename, ta0)
    258         return '%s<%s>' % (self.typename, ta0)
    259 
    260     def display_hint (self):
    261         return 'array'
    262 
    263 
    264 class MapPrinter:
    265     "Pretty printer for std::map and std::multimap."
    266 
    267     class Iterator:
    268 
    269         def __init__ (self, rbiter, node_type):
    270             self.rbiter    = rbiter
    271             self.node_type = node_type
    272             self.count     = 0
    273 
    274         def __iter__ (self):
    275             return self
    276 
    277         def next (self):
    278             if self.count % 2 == 0:
    279                 item = self.rbiter.next().dereference()
    280                 self.pair = (item.cast (self.node_type))['_M_value_field']
    281                 element = self.pair['first']
    282             else:
    283                 element = self.pair['second']
    284             count = self.count
    285             self.count += 1
    286             return ('[%d]' % count, element)
    287 
    288     def __init__ (self, typename, val):
    289         self.typename = typename
    290         self.val = val
    291 
    292     def children (self):
    293         key_type   = self.val.type.template_argument (0)
    294         value_type = self.val.type.template_argument (1)
    295         pair_type  \
    296             = lookup_stlport_type ('pair<%s const,%s>' % (key_type,value_type))
    297         node_type  \
    298             = lookup_stlport_priv_type ('_Rb_tree_node<%s >' % str (pair_type))
    299         return self.Iterator (RbtreeIterator (self.val), node_type)
    300 
    301     def to_string (self):
    302         ta0 = self.val.type.template_argument (0)
    303         count = get_non_debug_impl (self.val, '_M_t')['_M_node_count']
    304         return ('%s<%s> with %d elements' % (self.typename, ta0, count))
    305 
    306     def display_hint (self):
    307         return 'map'
    308 
    309 
    310 class SetPrinter:
    311     "Pretty printer for std::set and std::multiset."
    312 
    313     class Iterator:
    314         def __init__ (self, rbiter, node_type):
    315             self.rbiter    = rbiter
    316             self.node_type = node_type
    317             self.count     = 0
    318 
    319         def __iter__ (self):
    320             return self
    321 
    322         def next (self):
    323             item = self.rbiter.next().dereference()
    324             element = (item.cast (self.node_type))['_M_value_field']
    325             count = self.count
    326             self.count += 1
    327             return ('[%d]' % count, element)
    328 
    329     def __init__ (self, typename, val):
    330         self.typename = typename
    331         self.val = val
    332 
    333     def children (self):
    334         value_type = self.val.type.template_argument (0)
    335         node_type  \
    336             = lookup_stlport_priv_type ('_Rb_tree_node<%s>' % (value_type))
    337         return self.Iterator (RbtreeIterator (self.val), node_type)
    338 
    339     def to_string (self):
    340         ta0 = self.val.type.template_argument (0)
    341         count = get_non_debug_impl (self.val, '_M_t')['_M_node_count']
    342         return ('%s<%s> with %d elements' % (self.typename, ta0, count))
    343 
    344     def display_hint (self):
    345         return 'array'
    346 
    347 
    348 class SlistPrinter:
    349     "Pretty printer for std::slist."
    350 
    351     class Iterator:
    352         def __init__ (self, node_type, head):
    353             self.node_type = node_type
    354             self.item  = head['_M_next']
    355             self.count = 0
    356 
    357         def __iter__ (self):
    358             return self
    359 
    360         def next (self):
    361             if self.item == 0:
    362                 raise StopIteration
    363             node = self.item.cast (self.node_type).dereference()
    364             self.item = node['_M_next']
    365             count = self.count
    366             self.count += 1
    367             return ('[%d]' % count, node['_M_data'])
    368 
    369     def __init__(self, typename, val):
    370         self.typename = typename
    371         self.val = get_non_debug_impl (val)
    372 
    373     def children (self):
    374         ta0       = self.val.type.template_argument(0)
    375         node_type = lookup_stlport_priv_type ('_Slist_node<%s>' % ta0).pointer()
    376         return self.Iterator (node_type, self.val['_M_head']['_M_data'])
    377 
    378     def to_string (self):
    379         ta0 = self.val.type.template_argument (0)
    380         if self.val['_M_head']['_M_data']['_M_next'] == 0:
    381             return 'empty %s<%s>' % (self.typename, ta0)
    382         return '%s<%s>' % (self.typename, ta0)
    383 
    384     def display_hint (self):
    385         return 'array'
    386 
    387 
    388 class StringPrinter:
    389     "Pretty printer for std::string or std::wstring."
    390 
    391     def __init__ (self, _typename, val):
    392         self.val = get_non_debug_impl (val)
    393 
    394     def to_string (self):
    395         try:
    396             # STLport 5.2 and later
    397             return self.val['_M_start_of_storage']['_M_data']
    398         except RuntimeError:
    399             try:
    400                 # STLport 5.0 and 5.1 with short string optimization
    401                 static_buf = self.val['_M_buffers']['_M_static_buf']
    402                 data       = self.val['_M_end_of_storage']['_M_data']
    403                 if static_buf.address + 1 == data:
    404                     ta0    = self.val.type.template_argument (0)
    405                     start  = static_buf.cast (ta0.pointer())
    406                     finish = self.val['_M_finish']
    407                     if start == finish:
    408                         # STLport 5.0 without _STLP_FORCE_STRING_TERMINATION
    409                         return ""
    410                     return start
    411                 return self.val['_M_buffers']['_M_dynamic_buf']
    412             except RuntimeError:
    413                 # STLport 5.0 and 5.1 without short string optimization,
    414                 # and STLport 4.6
    415                 start  = self.val['_M_start']
    416                 finish = self.val['_M_finish']
    417                 if start == finish:
    418                     # STLport 5.0 without _STLP_FORCE_STRING_TERMINATION
    419                     return ""
    420                 return start
    421 
    422     def display_hint (self):
    423         return 'string'
    424 
    425 
    426 class VectorPrinter:
    427     "Pretty printer for std::vector."
    428 
    429     class Iterator:
    430 
    431         def __init__ (self, start, finish, bit_vector):
    432             self.bit_vector = bit_vector
    433             self.count      = 0
    434             if bit_vector:
    435                 self.item   = start['_M_p']
    436                 self.io     = start['_M_offset']
    437                 self.finish = finish['_M_p']
    438                 self.fo     = finish['_M_offset']
    439                 self.isize  = 8 * self.item.dereference().type.sizeof
    440             else:
    441                 self.item   = start
    442                 self.finish = finish
    443 
    444         def __iter__ (self):
    445             return self
    446 
    447         def next (self):
    448             count = self.count
    449             self.count += 1
    450             if self.bit_vector:
    451                 if self.item == self.finish and self.io == self.fo:
    452                     raise StopIteration
    453                 element = self.item.dereference()
    454                 value = 0
    455                 if element & (1 << self.io):
    456                     value = 1
    457                 self.io += 1
    458                 if self.io >= self.isize:
    459                     self.item += 1
    460                     self.io   =  0
    461                 return ('[%d]' % count, value)
    462             else:
    463                 if self.item == self.finish:
    464                     raise StopIteration
    465                 element = self.item.dereference()
    466                 self.item += 1
    467                 return ('[%d]' % count, element)
    468 
    469     def __init__ (self, typename, val):
    470         self.typename = typename
    471         self.val = get_non_debug_impl (val)
    472         self.bit_vector \
    473             = val.type.template_argument (0).code == gdb.TYPE_CODE_BOOL
    474 
    475     def children (self):
    476         start  = self.val['_M_start']
    477         finish = self.val['_M_finish']
    478         return self.Iterator (start, finish, self.bit_vector)
    479 
    480     def to_string (self):
    481         if self.bit_vector:
    482             start    = self.val['_M_start']['_M_p']
    483             so       = self.val['_M_start']['_M_offset']
    484             finish   = self.val['_M_finish']['_M_p']
    485             fo       = self.val['_M_finish']['_M_offset']
    486             end      = self.val['_M_end_of_storage']['_M_data']
    487             isize    = 8 * start.dereference().type.sizeof
    488             length   = (isize - so) + isize * (finish - start - 1) + fo
    489             capacity = isize * (end - start)
    490             return ('%s<bool> of length %d, capacity %d'
    491                 % (self.typename, length, capacity))
    492         else:
    493             start    = self.val['_M_start']
    494             finish   = self.val['_M_finish']
    495             end      = self.val['_M_end_of_storage']['_M_data']
    496             length   = finish - start
    497             capacity = end - start
    498             ta0      = self.val.type.template_argument (0)
    499             return ('%s<%s> of length %d, capacity %d'
    500                 % (self.typename, ta0, length, capacity))
    501 
    502     def display_hint (self):
    503         if print_vector_with_indices:
    504             return None
    505         else:
    506             return 'array'
    507 
    508 
    509 class WrapperPrinter:
    510     "Pretty printer for std::stack, std::queue, and std::priority_queue."
    511 
    512     def __init__ (self, typename, val):
    513         self.typename = typename
    514         self.val = val
    515         self.visualizer = gdb.default_visualizer (val['c'])
    516 
    517     def children (self):
    518         return self.visualizer.children()
    519 
    520     def to_string (self):
    521         ta0 = self.val.type.template_argument (0)
    522         return ('%s<%s>, wrapping %s'
    523             % (self.typename, ta0, self.visualizer.to_string()))
    524 
    525     def display_hint (self):
    526         if hasattr (self.visualizer, 'display_hint'):
    527             return self.visualizer.display_hint()
    528         return None
    529 
    530 
    531 class UnorderedMapPrinter:
    532     """Pretty printer for std::tr1::unordered_map
    533     and std::tr1::unordered_multimap."""
    534 
    535     class Iterator:
    536         def __init__ (self, node_type, head):
    537             self.node_type = node_type
    538             self.item  = head['_M_next']
    539             self.count = 0
    540 
    541         def __iter__ (self):
    542             return self
    543 
    544         def next (self):
    545             if self.item == 0 and self.count % 2 == 0:
    546                 raise StopIteration
    547             if self.count % 2 == 0:
    548                 self.pair = self.item.cast (self.node_type).dereference()
    549                 self.item = self.pair['_M_next']
    550                 element = self.pair['_M_data']['first']
    551             else:
    552                 element = self.pair['_M_data']['second']
    553             count = self.count
    554             self.count += 1
    555             return ('[%d]' % count, element)
    556 
    557     def __init__(self, typename, val):
    558         self.typename = typename
    559         self.val = get_non_debug_impl (val)
    560 
    561     def children (self):
    562         key_type   = self.val.type.template_argument (0)
    563         value_type = self.val.type.template_argument (1)
    564         pair_type  \
    565             = lookup_stlport_type ('pair<%s const,%s>' % (key_type,value_type))
    566         node_type  \
    567             = lookup_stlport_priv_type ('_Slist_node<%s >'
    568                 % str (pair_type)).pointer()
    569         elements = get_non_debug_impl (self.val, '_M_ht')['_M_elems']
    570         return self.Iterator (node_type, elements['_M_head']['_M_data'])
    571 
    572     def to_string (self):
    573         ta0 = self.val.type.template_argument (0)
    574         length = get_non_debug_impl (self.val, '_M_ht')['_M_num_elements']
    575         if length == 0:
    576             return 'empty %s<%s>' % (self.typename, ta0)
    577         return '%s<%s> with %d elements' % (self.typename, ta0, length)
    578 
    579     def display_hint (self):
    580         return 'map'
    581 
    582 
    583 class UnorderedSetPrinter:
    584     """Pretty printer for std::tr1::unordered_set
    585     and std::tr1::unordered_multiset."""
    586 
    587     class Iterator:
    588         def __init__ (self, node_type, head):
    589             self.node_type = node_type
    590             self.item  = head['_M_next']
    591             self.count = 0
    592 
    593         def __iter__ (self):
    594             return self
    595 
    596         def next (self):
    597             if self.item == 0:
    598                 raise StopIteration
    599             node = self.item.cast (self.node_type).dereference()
    600             self.item = node['_M_next']
    601             count = self.count
    602             self.count += 1
    603             return ('[%d]' % count, node['_M_data'])
    604 
    605     def __init__(self, typename, val):
    606         self.typename = typename
    607         self.val = get_non_debug_impl (val)
    608 
    609     def children (self):
    610         ta0 = self.val.type.template_argument(0)
    611         node_type = lookup_stlport_priv_type ('_Slist_node<%s>' % ta0).pointer()
    612         elements = get_non_debug_impl (self.val, '_M_ht')['_M_elems']
    613         return self.Iterator (node_type, elements['_M_head']['_M_data'])
    614 
    615     def to_string (self):
    616         ta0 = self.val.type.template_argument (0)
    617         length = get_non_debug_impl (self.val, '_M_ht')['_M_num_elements']
    618         if length == 0:
    619             return 'empty %s<%s>' % (self.typename, ta0)
    620         return '%s<%s> with %d elements' % (self.typename, ta0, length)
    621 
    622     def display_hint (self):
    623         return 'array'
    624 
    625 
    626 class AutoptrPrinter:
    627     "Pretty printer for std::auto_ptr."
    628 
    629     def __init__ (self, typename, val):
    630         self.typename = typename
    631         self.val = val
    632 
    633     def to_string (self):
    634         ta0 = self.val.type.template_argument (0)
    635         pointer = self.val['_M_p'].cast (ta0.pointer())
    636         if pointer == 0:
    637             return ('%s<%s> (empty)' % (self.typename, ta0))
    638         else:
    639             return ('%s<%s>, pointing to %s'
    640                 % (self.typename, ta0, pointer.dereference()))
    641 
    642     def display_hint (self):
    643         return None
    644 
    645 
    646 class SharedptrPrinter:
    647     "Pretty printer for std::shared_ptr and std::weak_ptr."
    648 
    649     def __init__ (self, typename, val):
    650         self.typename = typename
    651         self.val = val
    652 
    653     def to_string (self):
    654         ta0 = self.val.type.template_argument (0)
    655         pointer = self.val['px'].cast (ta0.pointer())
    656         if pointer == 0:
    657             return ('%s<%s> (empty)' % (self.typename, ta0))
    658         else:
    659             count = self.val['pn']['pi_']['use_count_']
    660             return ('%s<%s> (count %d), pointing to %s'
    661                 % (self.typename, ta0, count, pointer.dereference()))
    662 
    663     def display_hint (self):
    664         return None
    665 
    666 
    667 def lookup_function (val):
    668     "Look-up and return a pretty-printer that can print val."
    669 
    670     type = val.type
    671     if type.code == gdb.TYPE_CODE_REF:
    672         type = type.target()
    673     type = type.unqualified().strip_typedefs()
    674 
    675     typename = type.tag
    676     if typename == None:
    677         return None
    678 
    679     for function in pretty_printers_dict:
    680         if function.search (typename):
    681             return pretty_printers_dict[function] (val)
    682     return None
    683 
    684 
    685 def register_stlport_printers (obj):
    686     "Register STLport pretty-printers with object file obj."
    687 
    688     if obj == None:
    689         obj = gdb
    690     obj.pretty_printers.append (lookup_function)
    691 
    692 
    693 
    694 pretty_printers_dict = {}
    695 
    696 def add_entry (regex, printer, typename):
    697     prefix = "^(stlpd?_std|_STL|std)::"
    698     suffix = "<.*>$"
    699     if typename != None:
    700         typename = "std::" + typename
    701     if regex[0:5] == "boost":
    702         prefix = ""
    703     pretty_printers_dict[re.compile (prefix+regex+suffix)] \
    704         = lambda val: printer (typename, val)
    705 
    706 add_entry ("basic_string",   StringPrinter,  None)
    707 add_entry ("bitset",         BitsetPrinter,  "bitset")
    708 add_entry ("deque",          DequePrinter,   "deque")
    709 add_entry ("map",            MapPrinter,     "map")
    710 add_entry ("list",           ListPrinter,    "list")
    711 add_entry ("multimap",       MapPrinter,     "multimap")
    712 add_entry ("multiset",       SetPrinter,     "multiset")
    713 add_entry ("queue",          WrapperPrinter, "queue")
    714 add_entry ("priority_queue", WrapperPrinter, "priority_queue")
    715 add_entry ("set",            SetPrinter,     "set")
    716 add_entry ("slist",          SlistPrinter,   "slist")
    717 add_entry ("stack",          WrapperPrinter, "stack")
    718 add_entry ("vector",         VectorPrinter,  "vector")
    719 
    720 add_entry ("tr1::unordered_map",      UnorderedMapPrinter, "tr1::unordered_map")
    721 add_entry ("tr1::unordered_multimap", UnorderedMapPrinter, "tr1::unordered_multimap")
    722 add_entry ("tr1::unordered_set",      UnorderedSetPrinter, "tr1::unordered_set")
    723 add_entry ("tr1::unordered_multiset", UnorderedSetPrinter, "tr1::unordered_multiset")
    724 
    725 add_entry ("auto_ptr",          AutoptrPrinter,   "auto_ptr")
    726 add_entry ("boost::shared_ptr", SharedptrPrinter, "tr1::shared_ptr")
    727 add_entry ("boost::weak_ptr",   SharedptrPrinter, "tr1::weak_ptr")
    728