]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/lib/gdb/command/pretty_printers.py
a9027b3504656553f7c064f0a5c7715990594af7
1 # Pretty-printer commands.
2 # Copyright (C) 2010-2014 Free Software Foundation, Inc.
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 """GDB commands for working with pretty-printers."""
24 def parse_printer_regexps(arg
):
25 """Internal utility to parse a pretty-printer command argv.
28 arg: The arguments to the command. The format is:
29 [object-regexp [name-regexp]].
30 Individual printers in a collection are named as
31 printer-name;subprinter-name.
34 The result is a 3-tuple of compiled regular expressions, except that
35 the resulting compiled subprinter regexp is None if not provided.
38 SyntaxError: an error processing ARG
41 argv
= gdb
.string_to_argv(arg
);
43 object_regexp
= "" # match everything
44 name_regexp
= "" # match everything
47 raise SyntaxError("too many arguments")
49 object_regexp
= argv
[0]
51 name_subname
= argv
[1].split(";", 1)
52 name_regexp
= name_subname
[0]
53 if len(name_subname
) == 2:
54 subname_regexp
= name_subname
[1]
55 # That re.compile raises SyntaxError was determined empirically.
56 # We catch it and reraise it to provide a slightly more useful
57 # error message for the user.
59 object_re
= re
.compile(object_regexp
)
61 raise SyntaxError("invalid object regexp: %s" % object_regexp
)
63 name_re
= re
.compile (name_regexp
)
65 raise SyntaxError("invalid name regexp: %s" % name_regexp
)
66 if subname_regexp
is not None:
68 subname_re
= re
.compile(subname_regexp
)
70 raise SyntaxError("invalid subname regexp: %s" % subname_regexp
)
73 return(object_re
, name_re
, subname_re
)
76 def printer_enabled_p(printer
):
77 """Internal utility to see if printer (or subprinter) is enabled."""
78 if hasattr(printer
, "enabled"):
79 return printer
.enabled
84 class InfoPrettyPrinter(gdb
.Command
):
85 """GDB command to list all registered pretty-printers.
87 Usage: info pretty-printer [object-regexp [name-regexp]]
89 OBJECT-REGEXP is a regular expression matching the objects to list.
90 Objects are "global", the program space's file, and the objfiles within
93 NAME-REGEXP matches the name of the pretty-printer.
94 Individual printers in a collection are named as
95 printer-name;subprinter-name.
99 super(InfoPrettyPrinter
, self
).__init
__("info pretty-printer",
103 def enabled_string(printer
):
104 """Return "" if PRINTER is enabled, otherwise " [disabled]"."""
105 if printer_enabled_p(printer
):
111 def printer_name(printer
):
112 """Return the printer's name."""
113 if hasattr(printer
, "name"):
115 if hasattr(printer
, "__name__"):
116 return printer
.__name
__
117 # This "shouldn't happen", but the public API allows for
118 # direct additions to the pretty-printer list, and we shouldn't
119 # crash because someone added a bogus printer.
120 # Plus we want to give the user a way to list unknown printers.
123 def list_pretty_printers(self
, pretty_printers
, name_re
, subname_re
):
124 """Print a list of pretty-printers."""
125 # A potential enhancement is to provide an option to list printers in
126 # "lookup order" (i.e. unsorted).
127 sorted_pretty_printers
= sorted (copy
.copy(pretty_printers
),
128 key
= self
.printer_name
)
129 for printer
in sorted_pretty_printers
:
130 name
= self
.printer_name(printer
)
131 enabled
= self
.enabled_string(printer
)
132 if name_re
.match(name
):
133 print (" %s%s" % (name
, enabled
))
134 if (hasattr(printer
, "subprinters") and
135 printer
.subprinters
is not None):
136 sorted_subprinters
= sorted (copy
.copy(printer
.subprinters
),
137 key
= self
.printer_name
)
138 for subprinter
in sorted_subprinters
:
139 if (not subname_re
or
140 subname_re
.match(subprinter
.name
)):
143 self
.enabled_string(subprinter
)))
145 def invoke1(self
, title
, printer_list
,
146 obj_name_to_match
, object_re
, name_re
, subname_re
):
147 """Subroutine of invoke to simplify it."""
148 if printer_list
and object_re
.match(obj_name_to_match
):
150 self
.list_pretty_printers(printer_list
, name_re
, subname_re
)
152 def invoke(self
, arg
, from_tty
):
153 """GDB calls this to perform the command."""
154 (object_re
, name_re
, subname_re
) = parse_printer_regexps(arg
)
155 self
.invoke1("global pretty-printers:", gdb
.pretty_printers
,
156 "global", object_re
, name_re
, subname_re
)
157 cp
= gdb
.current_progspace()
158 self
.invoke1("progspace %s pretty-printers:" % cp
.filename
,
159 cp
.pretty_printers
, "progspace",
160 object_re
, name_re
, subname_re
)
161 for objfile
in gdb
.objfiles():
162 self
.invoke1(" objfile %s pretty-printers:" % objfile
.filename
,
163 objfile
.pretty_printers
, objfile
.filename
,
164 object_re
, name_re
, subname_re
)
167 def count_enabled_printers(pretty_printers
):
168 """Return a 2-tuple of number of enabled and total printers."""
171 for printer
in pretty_printers
:
172 if (hasattr(printer
, "subprinters")
173 and printer
.subprinters
is not None):
174 if printer_enabled_p(printer
):
175 for subprinter
in printer
.subprinters
:
176 if printer_enabled_p(subprinter
):
178 total
+= len(printer
.subprinters
)
180 if printer_enabled_p(printer
):
183 return (enabled
, total
)
186 def count_all_enabled_printers():
187 """Return a 2-tuble of the enabled state and total number of all printers.
188 This includes subprinters.
192 (t_enabled
, t_total
) = count_enabled_printers(gdb
.pretty_printers
)
193 enabled_count
+= t_enabled
194 total_count
+= t_total
195 (t_enabled
, t_total
) = count_enabled_printers(gdb
.current_progspace().pretty_printers
)
196 enabled_count
+= t_enabled
197 total_count
+= t_total
198 for objfile
in gdb
.objfiles():
199 (t_enabled
, t_total
) = count_enabled_printers(objfile
.pretty_printers
)
200 enabled_count
+= t_enabled
201 total_count
+= t_total
202 return (enabled_count
, total_count
)
205 def pluralize(text
, n
, suffix
="s"):
206 """Return TEXT pluralized if N != 1."""
208 return "%s%s" % (text
, suffix
)
213 def show_pretty_printer_enabled_summary():
214 """Print the number of printers enabled/disabled.
215 We count subprinters individually.
217 (enabled_count
, total_count
) = count_all_enabled_printers()
218 print ("%d of %d printers enabled" % (enabled_count
, total_count
))
221 def do_enable_pretty_printer_1 (pretty_printers
, name_re
, subname_re
, flag
):
222 """Worker for enabling/disabling pretty-printers.
225 pretty_printers: list of pretty-printers
226 name_re: regular-expression object to select printers
227 subname_re: regular expression object to select subprinters or None
229 flag: True for Enable, False for Disable
232 The number of printers affected.
233 This is just for informational purposes for the user.
236 for printer
in pretty_printers
:
237 if (hasattr(printer
, "name") and name_re
.match(printer
.name
) or
238 hasattr(printer
, "__name__") and name_re
.match(printer
.__name
__)):
239 if (hasattr(printer
, "subprinters") and
240 printer
.subprinters
is not None):
242 # Only record printers that change state.
243 if printer_enabled_p(printer
) != flag
:
244 for subprinter
in printer
.subprinters
:
245 if printer_enabled_p(subprinter
):
247 # NOTE: We preserve individual subprinter settings.
248 printer
.enabled
= flag
250 # NOTE: Whether this actually disables the subprinter
251 # depends on whether the printer's lookup function supports
252 # the "enable" API. We can only assume it does.
253 for subprinter
in printer
.subprinters
:
254 if subname_re
.match(subprinter
.name
):
255 # Only record printers that change state.
256 if (printer_enabled_p(printer
) and
257 printer_enabled_p(subprinter
) != flag
):
259 subprinter
.enabled
= flag
261 # This printer has no subprinters.
262 # If the user does "disable pretty-printer .* .* foo"
263 # should we disable printers that don't have subprinters?
264 # How do we apply "foo" in this context? Since there is no
265 # "foo" subprinter it feels like we should skip this printer.
266 # There's still the issue of how to handle
267 # "disable pretty-printer .* .* .*", and every other variation
268 # that can match everything. For now punt and only support
269 # "disable pretty-printer .* .*" (i.e. subname is elided)
270 # to disable everything.
272 # Only record printers that change state.
273 if printer_enabled_p(printer
) != flag
:
275 printer
.enabled
= flag
279 def do_enable_pretty_printer (arg
, flag
):
280 """Internal worker for enabling/disabling pretty-printers."""
281 (object_re
, name_re
, subname_re
) = parse_printer_regexps(arg
)
284 if object_re
.match("global"):
285 total
+= do_enable_pretty_printer_1(gdb
.pretty_printers
,
286 name_re
, subname_re
, flag
)
287 cp
= gdb
.current_progspace()
288 if object_re
.match("progspace"):
289 total
+= do_enable_pretty_printer_1(cp
.pretty_printers
,
290 name_re
, subname_re
, flag
)
291 for objfile
in gdb
.objfiles():
292 if object_re
.match(objfile
.filename
):
293 total
+= do_enable_pretty_printer_1(objfile
.pretty_printers
,
294 name_re
, subname_re
, flag
)
300 print ("%d %s %s" % (total
, pluralize("printer", total
), state
))
302 # Print the total list of printers currently enabled/disabled.
303 # This is to further assist the user in determining whether the result
304 # is expected. Since we use regexps to select it's useful.
305 show_pretty_printer_enabled_summary()
308 # Enable/Disable one or more pretty-printers.
310 # This is intended for use when a broken pretty-printer is shipped/installed
311 # and the user wants to disable that printer without disabling all the other
314 # A useful addition would be -v (verbose) to show each printer affected.
316 class EnablePrettyPrinter (gdb
.Command
):
317 """GDB command to enable the specified pretty-printer.
319 Usage: enable pretty-printer [object-regexp [name-regexp]]
321 OBJECT-REGEXP is a regular expression matching the objects to examine.
322 Objects are "global", the program space's file, and the objfiles within
325 NAME-REGEXP matches the name of the pretty-printer.
326 Individual printers in a collection are named as
327 printer-name;subprinter-name.
331 super(EnablePrettyPrinter
, self
).__init
__("enable pretty-printer",
334 def invoke(self
, arg
, from_tty
):
335 """GDB calls this to perform the command."""
336 do_enable_pretty_printer(arg
, True)
339 class DisablePrettyPrinter (gdb
.Command
):
340 """GDB command to disable the specified pretty-printer.
342 Usage: disable pretty-printer [object-regexp [name-regexp]]
344 OBJECT-REGEXP is a regular expression matching the objects to examine.
345 Objects are "global", the program space's file, and the objfiles within
348 NAME-REGEXP matches the name of the pretty-printer.
349 Individual printers in a collection are named as
350 printer-name;subprinter-name.
354 super(DisablePrettyPrinter
, self
).__init
__("disable pretty-printer",
357 def invoke(self
, arg
, from_tty
):
358 """GDB calls this to perform the command."""
359 do_enable_pretty_printer(arg
, False)
362 def register_pretty_printer_commands():
363 """Call from a top level script to install the pretty-printer commands."""
365 EnablePrettyPrinter()
366 DisablePrettyPrinter()
368 register_pretty_printer_commands()