65a7cabc88658a77ef832fe8ec2c7b28a273e5da
[platform/upstream/binutils.git] / gdb / testsuite / gdb.python / py-prettyprint.py
1 # Copyright (C) 2008-2012 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
16 # This file is part of the GDB testsuite.  It tests python pretty
17 # printers.
18
19 import re
20 import gdb
21
22 # Test returning a Value from a printer.
23 class string_print:
24     def __init__(self, val):
25         self.val = val
26
27     def to_string(self):
28         return self.val['whybother']['contents']
29
30 # Test a class-based printer.
31 class ContainerPrinter:
32     class _iterator:
33         def __init__ (self, pointer, len):
34             self.start = pointer
35             self.pointer = pointer
36             self.end = pointer + len
37
38         def __iter__(self):
39             return self
40
41         def next(self):
42             if self.pointer == self.end:
43                 raise StopIteration
44             result = self.pointer
45             self.pointer = self.pointer + 1
46             return ('[%d]' % int (result - self.start), result.dereference())
47
48     def __init__(self, val):
49         self.val = val
50
51     def to_string(self):
52         return 'container %s with %d elements' % (self.val['name'], self.val['len'])
53
54     def children(self):
55         return self._iterator(self.val['elements'], self.val['len'])
56
57 # Treats a container as array.
58 class ArrayPrinter:
59     class _iterator:
60         def __init__ (self, pointer, len):
61             self.start = pointer
62             self.pointer = pointer
63             self.end = pointer + len
64
65         def __iter__(self):
66             return self
67
68         def next(self):
69             if self.pointer == self.end:
70                 raise StopIteration
71             result = self.pointer
72             self.pointer = self.pointer + 1
73             return ('[%d]' % int (result - self.start), result.dereference())
74
75     def __init__(self, val):
76         self.val = val
77
78     def to_string(self):
79         return 'array %s with %d elements' % (self.val['name'], self.val['len'])
80
81     def children(self):
82         return self._iterator(self.val['elements'], self.val['len'])
83
84     def display_hint (self):
85         return 'array'
86
87 # Flag to make NoStringContainerPrinter throw an exception.
88 exception_flag = False
89
90 # Test a printer where to_string is None
91 class NoStringContainerPrinter:
92     class _iterator:
93         def __init__ (self, pointer, len):
94             self.start = pointer
95             self.pointer = pointer
96             self.end = pointer + len
97
98         def __iter__(self):
99             return self
100
101         def next(self):
102             if self.pointer == self.end:
103                 raise StopIteration
104             if exception_flag:
105                 raise gdb.MemoryError, 'hi bob'
106             result = self.pointer
107             self.pointer = self.pointer + 1
108             return ('[%d]' % int (result - self.start), result.dereference())
109
110     def __init__(self, val):
111         self.val = val
112
113     def to_string(self):
114         return None
115
116     def children(self):
117         return self._iterator(self.val['elements'], self.val['len'])
118
119 class pp_s:
120     def __init__(self, val):
121         self.val = val
122
123     def to_string(self):
124         a = self.val["a"]
125         b = self.val["b"]
126         if a.address != b:
127             raise Exception("&a(%s) != b(%s)" % (str(a.address), str(b)))
128         return " a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
129
130 class pp_ss:
131     def __init__(self, val):
132         self.val = val
133
134     def to_string(self):
135         return "a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
136
137 class pp_sss:
138     def __init__(self, val):
139         self.val = val
140
141     def to_string(self):
142         return "a=<" + str(self.val['a']) + "> b=<" + str(self.val["b"]) + ">"
143
144 class pp_multiple_virtual:
145     def __init__ (self, val):
146         self.val = val
147
148     def to_string (self):
149         return "pp value variable is: " + str (self.val['value'])
150
151 class pp_vbase1:
152     def __init__ (self, val):
153         self.val = val
154
155     def to_string (self):
156         return "pp class name: " + self.val.type.tag
157
158 class pp_nullstr:
159     def __init__(self, val):
160         self.val = val
161
162     def to_string(self):
163         return self.val['s'].string(gdb.target_charset())
164
165 class pp_ns:
166     "Print a std::basic_string of some kind"
167
168     def __init__(self, val):
169         self.val = val
170
171     def to_string(self):
172         len = self.val['length']
173         return self.val['null_str'].string (gdb.target_charset(), length = len)
174
175     def display_hint (self):
176         return 'string'
177
178 pp_ls_encoding = None
179
180 class pp_ls:
181     "Print a std::basic_string of some kind"
182
183     def __init__(self, val):
184         self.val = val
185
186     def to_string(self):
187         if pp_ls_encoding is not None:
188             return self.val['lazy_str'].lazy_string(encoding = pp_ls_encoding)
189         else:
190             return self.val['lazy_str'].lazy_string()
191
192     def display_hint (self):
193         return 'string'
194
195 class pp_hint_error:
196     "Throw error from display_hint"
197
198     def __init__(self, val):
199         self.val = val
200
201     def to_string(self):
202         return 'hint_error_val'
203
204     def display_hint (self):
205         raise Exception("hint failed")
206
207 class pp_children_as_list:
208     "Throw error from display_hint"
209
210     def __init__(self, val):
211         self.val = val
212
213     def to_string(self):
214         return 'children_as_list_val'
215
216     def children (self):
217         return [('one', 1)]
218
219 class pp_outer:
220     "Print struct outer"
221
222     def __init__ (self, val):
223         self.val = val
224
225     def to_string (self):
226         return "x = %s" % self.val['x']
227
228     def children (self):
229         yield 's', self.val['s']
230         yield 'x', self.val['x']
231
232 class MemoryErrorString:
233     "Raise an error"
234
235     def __init__(self, val):
236         self.val = val
237
238     def to_string(self):
239         raise gdb.MemoryError ("Cannot access memory.");
240
241     def display_hint (self):
242         return 'string'
243
244 class pp_eval_type:
245     def __init__(self, val):
246         self.val = val
247
248     def to_string(self):
249         gdb.execute("bt", to_string=True)
250         return "eval=<" + str(gdb.parse_and_eval("eval_func (123456789, 2, 3, 4, 5, 6, 7, 8)")) + ">"
251
252 def lookup_function (val):
253     "Look-up and return a pretty-printer that can print val."
254
255     # Get the type.
256     type = val.type
257
258     # If it points to a reference, get the reference.
259     if type.code == gdb.TYPE_CODE_REF:
260         type = type.target ()
261
262     # Get the unqualified type, stripped of typedefs.
263     type = type.unqualified ().strip_typedefs ()
264
265     # Get the type name.    
266     typename = type.tag
267
268     if typename == None:
269         return None
270
271     # Iterate over local dictionary of types to determine
272     # if a printer is registered for that type.  Return an
273     # instantiation of the printer if found.
274     for function in pretty_printers_dict:
275         if function.match (typename):
276             return pretty_printers_dict[function] (val)
277         
278     # Cannot find a pretty printer.  Return None.
279
280     return None
281
282 def disable_lookup_function ():
283     lookup_function.enabled = False
284
285 def enable_lookup_function ():
286     lookup_function.enabled = True
287
288 def register_pretty_printers ():
289     pretty_printers_dict[re.compile ('^struct s$')]   = pp_s
290     pretty_printers_dict[re.compile ('^s$')]   = pp_s
291     pretty_printers_dict[re.compile ('^S$')]   = pp_s
292
293     pretty_printers_dict[re.compile ('^struct ss$')]  = pp_ss
294     pretty_printers_dict[re.compile ('^ss$')]  = pp_ss
295     pretty_printers_dict[re.compile ('^const S &$')]   = pp_s
296     pretty_printers_dict[re.compile ('^SSS$')]  = pp_sss
297     
298     pretty_printers_dict[re.compile ('^VirtualTest$')] =  pp_multiple_virtual
299     pretty_printers_dict[re.compile ('^Vbase1$')] =  pp_vbase1
300
301     pretty_printers_dict[re.compile ('^struct nullstr$')] = pp_nullstr
302     pretty_printers_dict[re.compile ('^nullstr$')] = pp_nullstr
303     
304     # Note that we purposely omit the typedef names here.
305     # Printer lookup is based on canonical name.
306     # However, we do need both tagged and untagged variants, to handle
307     # both the C and C++ cases.
308     pretty_printers_dict[re.compile ('^struct string_repr$')] = string_print
309     pretty_printers_dict[re.compile ('^struct container$')] = ContainerPrinter
310     pretty_printers_dict[re.compile ('^struct justchildren$')] = NoStringContainerPrinter
311     pretty_printers_dict[re.compile ('^string_repr$')] = string_print
312     pretty_printers_dict[re.compile ('^container$')] = ContainerPrinter
313     pretty_printers_dict[re.compile ('^justchildren$')] = NoStringContainerPrinter
314     
315     pretty_printers_dict[re.compile ('^struct ns$')]  = pp_ns
316     pretty_printers_dict[re.compile ('^ns$')]  = pp_ns
317
318     pretty_printers_dict[re.compile ('^struct lazystring$')]  = pp_ls
319     pretty_printers_dict[re.compile ('^lazystring$')]  = pp_ls
320
321     pretty_printers_dict[re.compile ('^struct outerstruct$')]  = pp_outer
322     pretty_printers_dict[re.compile ('^outerstruct$')]  = pp_outer
323
324     pretty_printers_dict[re.compile ('^struct hint_error$')]  = pp_hint_error
325     pretty_printers_dict[re.compile ('^hint_error$')]  = pp_hint_error
326
327     pretty_printers_dict[re.compile ('^struct children_as_list$')]  = pp_children_as_list
328     pretty_printers_dict[re.compile ('^children_as_list$')]  = pp_children_as_list
329
330     pretty_printers_dict[re.compile ('^memory_error$')]  = MemoryErrorString
331
332     pretty_printers_dict[re.compile ('^eval_type_s$')] = pp_eval_type
333
334 pretty_printers_dict = {}
335
336 register_pretty_printers ()
337 gdb.pretty_printers.append (lookup_function)