17"""Utilities for working with pretty-printers."""
26 """A basic pretty-printer.
29 name: A unique string among all printers for the context in which
30 it is defined (objfile, progspace, or global(gdb)), and should
31 meaningfully describe what can be pretty-printed.
32 E.g., "StringPiece" or "protobufs".
33 subprinters: An iterable object with each element having a `name'
34 attribute, and, potentially, "enabled" attribute.
35 Or this is None if there are no subprinters.
36 enabled: A boolean indicating if the printer is enabled.
38 Subprinters are for situations where "one" pretty-printer is actually a
39 collection of several printers. E.g., The libstdc++ pretty-printer has
40 a pretty-printer for each of several different types, based on regexps.
54 raise NotImplementedError(
"PrettyPrinter __call__")
58 """Baseclass for sub-pretty-printers.
60 Sub-pretty-printers needn't use this, but it formalizes what's needed.
63 name: The name of the subprinter.
64 enabled: A boolean indicating if the subprinter is enabled.
73 """Register pretty-printer PRINTER with OBJ.
75 The printer is added to the front of the search list, thus one can override
76 an existing printer if one needs to. Use a different name when overriding
77 an existing printer, otherwise an exception will be raised; multiple
78 printers with the same name are disallowed.
81 obj: Either an objfile, progspace, or None (in which case the printer
82 is registered globally).
83 printer: Either a function of one argument (old way) or any object
84 which has attributes: name, enabled, __call__.
85 replace: If True replace any existing copy of the printer.
86 Otherwise if the printer already exists raise an exception.
92 TypeError: A problem with the type of the printer.
93 ValueError: The printer's name contains a semicolon ";".
94 RuntimeError: A printer with the same name is already registered.
96 If the caller wants the printer to be listable and disableable, it must
97 follow the PrettyPrinter API. This applies to the old way (functions) too.
98 If printer is an object, __call__ is a method of two arguments:
99 self, and the value to be pretty-printed. See PrettyPrinter.
106 if not hasattr(printer,
"__name__")
and not hasattr(printer,
"name"):
107 raise TypeError(
"printer missing attribute: name")
108 if hasattr(printer,
"name")
and not hasattr(printer,
"enabled"):
109 raise TypeError(
"printer missing attribute: enabled")
110 if not hasattr(printer,
"__call__"):
111 raise TypeError(
"printer missing attribute: __call__")
113 if hasattr(printer,
"name"):
116 name = printer.__name__
117 if obj
is None or obj
is gdb:
118 if gdb.parameter(
"verbose"):
119 gdb.write(
"Registering global %s pretty-printer ...\n" % name)
122 if gdb.parameter(
"verbose"):
124 "Registering %s pretty-printer for %s ...\n" % (name, obj.filename)
129 if hasattr(printer,
"name"):
130 if not isinstance(printer.name, str):
131 raise TypeError(
"printer name is not a string")
135 if printer.name.find(
";") >= 0:
136 raise ValueError(
"semicolon ';' in printer name")
142 for p
in obj.pretty_printers:
143 if hasattr(p,
"name")
and p.name == printer.name:
145 del obj.pretty_printers[i]
149 "pretty-printer already registered: %s" % printer.name
153 obj.pretty_printers.insert(0, printer)
157 """Class for implementing a collection of regular-expression based pretty-printers.
161 pretty_printer = RegexpCollectionPrettyPrinter("my_library")
162 pretty_printer.add_printer("myclass1", "^myclass1$", MyClass1Printer)
164 pretty_printer.add_printer("myclassN", "^myclassN$", MyClassNPrinter)
165 register_pretty_printer(obj, pretty_printer)
176 super(RegexpCollectionPrettyPrinter, self).
__init__(name, [])
179 """Add a printer to the list.
181 The printer is added to the end of the list.
184 name: The name of the subprinter.
185 regexp: The regular expression, as a string.
186 gen_printer: A function/method that given a value returns an
187 object to pretty-print it.
201 """Lookup the pretty-printer for the provided value."""
206 typename = val.type.name
214 if printer.enabled
and printer.compiled_re.search(typename):
215 return printer.gen_printer(val)
234 flag_list.append(e_name)
237 if not any_found
or v != 0:
239 flag_list.append(
"<unknown: 0x%x>" % v)
240 return "0x%x [%s]" % (int(self.
__val),
" | ".join(flag_list))
244 """A pretty-printer which can be used to print a flag-style enumeration.
245 A flag-style enumeration is one where the enumerators are or'd
246 together to create values. The new printer will print these
247 symbolically using '|' notation. The printer must be registered
248 manually. This printer is most useful when an enum is flag-like,
249 but has some overlap. GDB's built-in printing will not handle
250 this case, but this printer will attempt to."""
253 super(FlagEnumerationPrinter, self).
__init__(enum_type)
259 flags = gdb.lookup_type(self.
name)
261 for field
in flags.fields():
262 self.
enumerators.append((field.name, field.enumval))
274 """A no-op pretty printer that wraps a scalar value."""
280 return self.
__value.format_string(raw=
True)
284 """A no-op pretty printer that wraps a pointer or reference."""
290 return self.
__value.format_string(deref_refs=
False)
296 return "value", self.
__value.referenced_value()
299 yield "value", self.
__value.referenced_value()
303 """A no-op pretty printer that wraps an array value."""
307 (low, high) = ty.range()
312 range_type = ty.fields()[0].type
313 if range_type.target().code == gdb.TYPE_CODE_ENUM:
314 e_values = range_type.target().fields()
316 e_values = itertools.dropwhile(
lambda x: x.enumval < low, e_values)
318 e_values = itertools.takewhile(
lambda x: x.enumval <= high, e_values)
320 high = len(list(e_values)) - 1
342 """A no-op pretty printer that wraps a struct or union value."""
352 for field
in self.
__ty.fields():
353 if hasattr(field,
"bitpos")
and field.name
is not None:
354 yield (field.name, self.
__value[field])
358 """Given a gdb.Value, wrap it in a pretty-printer.
360 If a pretty-printer is found by the usual means, it is returned.
361 Otherwise, VALUE will be wrapped in a no-op visualizer."""
363 result = gdb.default_visualizer(value)
364 if result
is not None:
368 ty = value.type.strip_typedefs()
369 if ty.is_string_like:
371 elif ty.code == gdb.TYPE_CODE_ARRAY:
373 elif ty.is_array_like:
374 value = value.to_array()
375 ty = value.type.strip_typedefs()
377 elif ty.code
in (gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION):
382 gdb.TYPE_CODE_RVALUE_REF,
402 _builtin_pretty_printers.add_printer(name, regexp, printer)
__init__(self, enum_type)
__init__(self, ty, value)
__init__(self, ty, value)
__init__(self, name, subprinters=None)
__init__(self, name, regexp, gen_printer)
add_printer(self, name, regexp, gen_printer)
__init__(self, enumerators, val)
register_pretty_printer(obj, printer, replace=False)
add_builtin_pretty_printer(name, regexp, printer)