update credits
[LibreOffice.git] / solenv / gdb / boost / ptr_container.py
blob9e9a66feb5afc171f2184744deeca75c8d4b6cfb
1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
2 # GDB pretty printers for Boost.Pointer Container.
4 # Copyright (C) 2012 Red Hat, Inc., David Tardon <dtardon@redhat.com>
6 # This file is part of boost-gdb-printers.
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 import gdb
24 from boost.lib.unordered import Map, Set
26 import boost.util.printing as printing
28 std = None
30 class PtrStdPrinterBase(object):
32 def __init__(self, typename, value, seq_tag):
33 self._import_std()
34 self.typename = typename
35 self.value = value
37 # (try to) init printer of underlying std sequence and get elements
38 printer = self._get_sequence_printer(seq_tag)
39 if printer:
40 seq = value['c_']
41 if str(seq.type.strip_typedefs()).startswith('std::__debug::'):
42 seq_typename = 'std::__debug::%s' % seq_tag
43 else:
44 seq_typename = 'std::%s' % seq_tag
45 self.sequence = list(printer(seq_typename, seq).children())
46 else:
47 self.sequence = None
49 def to_string(self):
50 if self.sequence != None:
51 length = len(self.sequence)
52 if length:
53 return "%s %s" % (self.typename, self.print_size(length))
54 else:
55 return "empty %s" % self.typename
56 else:
57 return "opaque %s" % self.typename
59 def children(self):
60 return self._iterator(self.sequence, self.value.type.template_argument(0))
62 class _iterator(object):
64 def __init__(self, sequence, type):
65 self.impl = iter(sequence)
66 self.type = type.pointer()
68 def __iter__(self):
69 return self
71 def next(self):
72 (index, value) = self.impl.next()
73 return (index, value.cast(self.type).dereference())
75 def _import_std(self):
76 global std
77 if not std:
78 try:
79 import libstdcxx.v6.printers
80 std = libstdcxx.v6.printers
81 except:
82 pass
84 def _get_sequence_printer(self, typename):
85 if typename == "deque":
86 return std.StdDequePrinter
87 if typename == "list":
88 return std.StdListPrinter
89 if typename == "map":
90 return std.StdMapPrinter
91 if typename == "set":
92 return std.StdSetPrinter
93 if typename == "vector":
94 return std.StdVectorPrinter
96 class PtrSequencePrinter(PtrStdPrinterBase):
98 def __init__(self, typename, value, seq_tag):
99 super(PtrSequencePrinter, self).__init__(typename, value, seq_tag)
101 def print_size(self, size):
102 return "of length %s" % size
104 def display_hint(self):
105 return 'array'
107 class PtrSetPrinter(PtrStdPrinterBase):
109 def __init__(self, typename, value):
110 super(PtrSetPrinter, self).__init__(typename, value, 'set')
112 def print_size(self, size):
113 return "with %s elements" % size
115 def display_hint(self):
116 return 'array'
118 class PtrMapPrinter(PtrStdPrinterBase):
120 def __init__(self, typename, value):
121 super(PtrMapPrinter, self).__init__(typename, value, 'map')
123 def children(self):
124 type = self.value.type
125 return self._iterator(self.sequence, type.template_argument(0), type.template_argument(1))
127 class _iterator(object):
129 def __init__(self, sequence, key_type, value_type):
130 self.impl = iter(sequence)
131 self.key_type = key_type
132 self.value_type = value_type.pointer()
133 self.key = True
135 def __iter__(self):
136 return self
138 def next(self):
139 (index, value) = self.impl.next()
140 if self.key:
141 value = value.cast(self.key_type)
142 else:
143 value = value.cast(self.value_type).dereference()
144 self.key = not self.key
145 return (index, value)
147 def display_hint(self):
148 return 'map'
150 def print_size(self, size):
151 return "with %s elements" % (size / 2)
153 class PtrBoostPrinterBase(object):
155 def __init__(self, typename, value, container, iterator, value_type):
156 self.typename = typename
157 self.impl = container(value['c_'])
158 self.iterator = iterator
159 self.value_type = value_type.pointer()
161 def to_string(self):
162 if self.impl.empty():
163 return "empty " + self.typename
164 else:
165 return "%s with %s elements" % (self.typename, len(self.impl))
167 def children(self):
168 return self.iterator(iter(self.impl), self.value_type)
170 class PtrUnorderedMapPrinter(PtrBoostPrinterBase):
172 def __init__(self, typename, value):
173 super(PtrUnorderedMapPrinter, self).__init__(typename, value, Map, self._iterator,
174 value.type.template_argument(1))
176 def display_hint(self):
177 return 'map'
179 class _iterator(object):
181 def __init__(self, impl, value_type):
182 self.impl = impl
183 self.step = True
184 self.value = None
185 self.value_type = value_type
187 def __iter__(self):
188 return self
190 def next(self):
191 if self.step:
192 self.value = self.impl.next()
193 value = self.value[0]
194 else:
195 value = self.value[1].cast(self.value_type).dereference()
196 self.step = not self.step
197 return ("", value)
199 class PtrUnorderedSetPrinter(PtrBoostPrinterBase):
201 def __init__(self, typename, value):
202 super(PtrUnorderedSetPrinter, self).__init__(typename, value, Set, self._iterator,
203 value.type.template_argument(0))
205 def display_hint(self):
206 return 'array'
208 class _iterator(object):
210 def __init__(self, impl, value_type):
211 self.impl = impl
212 self.value_type = value_type
214 def __iter__(self):
215 return self
217 def next(self):
218 return ("", self.impl.next()[1].cast(self.value_type).dereference())
220 printer = None
222 def build_pretty_printers():
223 global printer
225 if printer != None:
226 return
228 printer = printing.Printer("boost.ptr_container")
230 printer.add('boost::ptr_deque', (lambda t, v: PtrSequencePrinter(t, v, "deque")))
231 printer.add('boost::ptr_list', (lambda t, v: PtrSequencePrinter(t, v, "list")))
232 printer.add('boost::ptr_map', PtrMapPrinter)
233 printer.add('boost::ptr_multimap', PtrMapPrinter)
234 printer.add('boost::ptr_multiset', PtrSetPrinter)
235 printer.add('boost::ptr_set', PtrSetPrinter)
236 printer.add('boost::ptr_unordered_map', PtrUnorderedMapPrinter)
237 printer.add('boost::ptr_unordered_multimap', PtrUnorderedMapPrinter)
238 printer.add('boost::ptr_unordered_multiset', PtrUnorderedSetPrinter)
239 printer.add('boost::ptr_unordered_set', PtrUnorderedSetPrinter)
240 printer.add('boost::ptr_vector', (lambda t, v: PtrSequencePrinter(t, v, "vector")))
242 def register_pretty_printers(obj):
243 printing.register_pretty_printer(printer, obj)
245 build_pretty_printers()
247 # vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab: