From: Andrew Burgess Date: Sun, 5 Oct 2025 17:51:12 +0000 (+0100) Subject: gdb/python: make use of gdb.Style for shipped Python commands X-Git-Tag: binutils-2_46~1354 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01040a24d953136b7b3f4b17e0f6b3489acb7199;p=thirdparty%2Fbinutils-gdb.git gdb/python: make use of gdb.Style for shipped Python commands With the recent addition of the gdb.Style Python API, this commit goes through the gdb.Command sub-classes which we ship with GDB and adds some styling support. This adds 'title' style in a couple of places where we layout tables. And uses 'filename' style where we are printing filenames. While I was making these changes I've made a couple of related fixes. In 'info frame-filter', 'info missing-objfile-handlers', 'info pretty-printer', and 'info xmethod', we would sometimes print the gdb.Progspace.filename unconditionally, even though this field can sometimes be None. To better handle this case, I now check for None, and print '' instead. We already printed that same string for the program space name in at least one other case, so this change makes things a little more consistent. I don't format the '' string with the filename style, only if we have an actual filename does the string get formatted. The other fix I made was in 'maint info python-disassemblers'. Here I've added an extra space between the two columns in the output table. The two columns are 'Architecture' and 'Disassembler Name'. Given that one column contains a white space, it was rather confusing having a single space between columns. Luckily the tests don't depend on a single space, so nothing needs updating for this change. Additionally, in 'info frame-filter' I've updated the exception handling to use the gdb.warning function, rather than just printing a line of output. This means that should this case occur we get the neat little emoji. We have no tests that trigger this warning, and I couldn't figure out how to write one. In this end, I just hacked the Python code to raise an exception and checked the output looked reasonable. I suspect this warning might be a hard one to trigger! Approved-By: Tom Tromey --- diff --git a/gdb/python/lib/gdb/command/frame_filters.py b/gdb/python/lib/gdb/command/frame_filters.py index be7be9aa5fc..4b2d214d697 100644 --- a/gdb/python/lib/gdb/command/frame_filters.py +++ b/gdb/python/lib/gdb/command/frame_filters.py @@ -68,7 +68,11 @@ class InfoFrameFilter(gdb.Command): return 0 print(title) - print(" Priority Enabled Name") + style = gdb.Style("title") + print( + " %s %s %s" + % (style.apply("Priority"), style.apply("Enabled"), style.apply("Name")) + ) for frame_filter in sorted_frame_filters: name = frame_filter[0] try: @@ -77,9 +81,8 @@ class InfoFrameFilter(gdb.Command): self.enabled_string(gdb.frames.get_enabled(frame_filter[1])) ) print(" %s %s %s" % (priority, enabled, name)) - except Exception: - e = sys.exc_info()[1] - print(" Error printing filter '" + name + "': " + str(e)) + except Exception as e: + gdb.warning("Error printing filter '" + name + "': " + str(e)) if blank_line: print("") return 1 @@ -87,14 +90,20 @@ class InfoFrameFilter(gdb.Command): def invoke(self, arg, from_tty): any_printed = self.print_list("global frame-filters:", gdb.frame_filters, True) + file_style = gdb.Style("filename") cp = gdb.current_progspace() + cp_filename = cp.filename + if cp_filename is None: + cp_filename = "" + else: + cp_filename = file_style.apply(cp_filename) any_printed += self.print_list( - "progspace %s frame-filters:" % cp.filename, cp.frame_filters, True + "progspace %s frame-filters:" % cp_filename, cp.frame_filters, True ) for objfile in gdb.objfiles(): any_printed += self.print_list( - "objfile %s frame-filters:" % objfile.filename, + "objfile %s frame-filters:" % file_style.apply(objfile.filename), objfile.frame_filters, False, ) diff --git a/gdb/python/lib/gdb/command/missing_files.py b/gdb/python/lib/gdb/command/missing_files.py index 09d9684dca2..b2477ce0efb 100644 --- a/gdb/python/lib/gdb/command/missing_files.py +++ b/gdb/python/lib/gdb/command/missing_files.py @@ -118,10 +118,16 @@ class InfoMissingFileHandlers(gdb.Command): def invoke(self, arg, from_tty): locus_re, name_re = parse_missing_file_command_args(arg) + file_style = gdb.Style("filename") if locus_re.match("progspace") and locus_re.pattern != "": cp = gdb.current_progspace() + cp_filename = cp.filename + if cp.filename is None: + cp_filename = "" + else: + cp_filename = file_style.apply(cp_filename) self.list_handlers( - "Progspace %s:" % cp.filename, cp.missing_file_handlers, name_re + "Progspace %s:" % cp_filename, cp.missing_file_handlers, name_re ) for progspace in gdb.progspaces(): @@ -133,7 +139,7 @@ class InfoMissingFileHandlers(gdb.Command): else: msg = "Progspace :" else: - msg = "Progspace %s:" % filename + msg = "Progspace %s:" % file_style.apply(filename) self.list_handlers( msg, progspace.missing_file_handlers, diff --git a/gdb/python/lib/gdb/command/pretty_printers.py b/gdb/python/lib/gdb/command/pretty_printers.py index f62d329c54d..cdf90543cac 100644 --- a/gdb/python/lib/gdb/command/pretty_printers.py +++ b/gdb/python/lib/gdb/command/pretty_printers.py @@ -161,9 +161,15 @@ class InfoPrettyPrinter(gdb.Command): name_re, subname_re, ) + file_style = gdb.Style("filename") cp = gdb.current_progspace() + cp_filename = cp.filename + if cp_filename is None: + cp_filename = "" + else: + cp_filename = file_style.apply(cp_filename) self.invoke1( - "progspace %s pretty-printers:" % cp.filename, + "progspace %s pretty-printers:" % cp_filename, cp.pretty_printers, "progspace", object_re, @@ -172,7 +178,7 @@ class InfoPrettyPrinter(gdb.Command): ) for objfile in gdb.objfiles(): self.invoke1( - "objfile %s pretty-printers:" % objfile.filename, + "objfile %s pretty-printers:" % file_style.apply(objfile.filename), objfile.pretty_printers, objfile.filename, object_re, diff --git a/gdb/python/lib/gdb/command/xmethods.py b/gdb/python/lib/gdb/command/xmethods.py index 719c1463d4a..2f870746bdc 100644 --- a/gdb/python/lib/gdb/command/xmethods.py +++ b/gdb/python/lib/gdb/command/xmethods.py @@ -101,6 +101,7 @@ def get_method_matchers_in_loci(loci, locus_re, matcher_re): A dict of matching xmethod matchers. The keys of the dict are the filenames of the loci the xmethod matchers belong to. """ + file_style = gdb.Style("filename") xm_dict = {} for locus in loci: if isinstance(locus, gdb.Progspace): @@ -111,7 +112,12 @@ def get_method_matchers_in_loci(loci, locus_re, matcher_re): if not locus_re.match(locus.filename): continue locus_type = "objfile" - locus_str = "%s %s" % (locus_type, locus.filename) + filename = locus.filename + if filename is None: + filename = "" + else: + filename = file_style.apply(filename) + locus_str = "%s %s" % (locus_type, filename) xm_dict[locus_str] = [m for m in locus.xmethods if matcher_re.match(m.name)] return xm_dict diff --git a/gdb/python/lib/gdb/disassembler.py b/gdb/python/lib/gdb/disassembler.py index 8f8e768f637..59566788210 100644 --- a/gdb/python/lib/gdb/disassembler.py +++ b/gdb/python/lib/gdb/disassembler.py @@ -155,9 +155,21 @@ class maint_info_py_disassemblers_cmd(gdb.Command): # Now print the dictionary of registered disassemblers out to # the user. match_tag = "\t(Matches current architecture)" - fmt_len = max(longest_arch_name, len("Architecture")) - format_string = "{:" + str(fmt_len) + "s} {:s}" - print(format_string.format("Architecture", "Disassember Name")) + arch_title = "Architecture" + fmt_len = max(longest_arch_name, len(arch_title)) + format_string = "{:" + str(fmt_len) + "s} {:s}" + padding_string = " " * (fmt_len - len(arch_title)) + title_style = gdb.Style("title") + # We cannot use FORMAT_STRING to layout the title line, as + # Python is unable to calculate the length of a styled string. + # Instead use PADDING_STRING to manually layout the columns. + print( + "{:s}{:s} {:s}".format( + title_style.apply(arch_title), + padding_string, + title_style.apply("Disassember Name"), + ) + ) for architecture in _disassemblers_dict: if architecture is not None: name = _disassemblers_dict[architecture].name