Files
Simon Marchi 13123da89a gdb: re-format Python files using black 21.4b0
Re-format all Python files using black [1] version 21.4b0.  The goal is
that from now on, we keep all Python files formatted using black.  And
that we never have to discuss formatting during review (for these files
at least) ever again.

One change is needed in gdb.python/py-prettyprint.exp, because it
matches the string representation of an exception, which shows source
code.  So the change in formatting must be replicated in the expected
regexp.

To document our usage of black I plan on adding this to the "GDB Python
Coding Standards" wiki page [2]:

--8<--

All Python source files under the `gdb/` directory must be formatted
using black version 21.4b0.

This specific version can be installed using:

    $ pip3 install 'black == 21.4b0'

All you need to do to re-format files is run `black <file/directory>`,
and black will re-format any Python file it finds in there.  It runs
quite fast, so the simplest is to do:

    $ black gdb/

from the top-level.

If you notice that black produces changes unrelated to your patch, it's
probably because someone forgot to run it before you.  In this case,
don't include unrelated hunks in your patch.  Push an obvious patch
fixing the formatting and rebase your work on top of that.

-->8--

Once this is merged, I plan on setting a up an `ignoreRevsFile`
config so that git-blame ignores this commit, as described here:

  https://github.com/psf/black#migrating-your-code-style-without-ruining-git-blame

I also plan on working on a git commit hook (checked in the repo) to
automatically check the formatting of the Python files on commit.

[1] https://pypi.org/project/black/
[2] https://sourceware.org/gdb/wiki/Internals%20GDB-Python-Coding-Standards

gdb/ChangeLog:

	* Re-format all Python files using black.

gdb/testsuite/ChangeLog:

	* Re-format all Python files using black.
	* gdb.python/py-prettyprint.exp (run_lang_tests): Adjust.

Change-Id: I28588a22c2406afd6bc2703774ddfff47cd61919
2021-05-07 10:56:20 -04:00

200 lines
6.3 KiB
Python

# Unwinder commands.
# Copyright 2015-2021 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import gdb
import re
def validate_regexp(exp, idstring):
try:
return re.compile(exp)
except SyntaxError:
raise SyntaxError("Invalid %s regexp: %s." % (idstring, exp))
def parse_unwinder_command_args(arg):
"""Internal utility to parse unwinder command argv.
Arguments:
arg: The arguments to the command. The format is:
[locus-regexp [name-regexp]]
Returns:
A 2-tuple of compiled regular expressions.
Raises:
SyntaxError: an error processing ARG
"""
argv = gdb.string_to_argv(arg)
argc = len(argv)
if argc > 2:
raise SyntaxError("Too many arguments.")
locus_regexp = ""
name_regexp = ""
if argc >= 1:
locus_regexp = argv[0]
if argc >= 2:
name_regexp = argv[1]
return (
validate_regexp(locus_regexp, "locus"),
validate_regexp(name_regexp, "unwinder"),
)
class InfoUnwinder(gdb.Command):
"""GDB command to list unwinders.
Usage: info unwinder [LOCUS-REGEXP [NAME-REGEXP]]
LOCUS-REGEXP is a regular expression matching the location of the
unwinder. If it is omitted, all registered unwinders from all
loci are listed. A locus can be 'global', 'progspace' to list
the unwinders from the current progspace, or a regular expression
matching filenames of objfiles.
NAME-REGEXP is a regular expression to filter unwinder names. If
this omitted for a specified locus, then all registered unwinders
in the locus are listed."""
def __init__(self):
super(InfoUnwinder, self).__init__("info unwinder", gdb.COMMAND_STACK)
def list_unwinders(self, title, unwinders, name_re):
"""Lists the unwinders whose name matches regexp.
Arguments:
title: The line to print before the list.
unwinders: The list of the unwinders.
name_re: unwinder name filter.
"""
if not unwinders:
return
print(title)
for unwinder in unwinders:
if name_re.match(unwinder.name):
print(
" %s%s"
% (unwinder.name, "" if unwinder.enabled else " [disabled]")
)
def invoke(self, arg, from_tty):
locus_re, name_re = parse_unwinder_command_args(arg)
if locus_re.match("global"):
self.list_unwinders("Global:", gdb.frame_unwinders, name_re)
if locus_re.match("progspace"):
cp = gdb.current_progspace()
self.list_unwinders(
"Progspace %s:" % cp.filename, cp.frame_unwinders, name_re
)
for objfile in gdb.objfiles():
if locus_re.match(objfile.filename):
self.list_unwinders(
"Objfile %s:" % objfile.filename, objfile.frame_unwinders, name_re
)
def do_enable_unwinder1(unwinders, name_re, flag):
"""Enable/disable unwinders whose names match given regex.
Arguments:
unwinders: The list of unwinders.
name_re: Unwinder name filter.
flag: Enable/disable.
Returns:
The number of unwinders affected.
"""
total = 0
for unwinder in unwinders:
if name_re.match(unwinder.name):
unwinder.enabled = flag
total += 1
return total
def do_enable_unwinder(arg, flag):
"""Enable/disable unwinder(s)."""
(locus_re, name_re) = parse_unwinder_command_args(arg)
total = 0
if locus_re.match("global"):
total += do_enable_unwinder1(gdb.frame_unwinders, name_re, flag)
if locus_re.match("progspace"):
total += do_enable_unwinder1(
gdb.current_progspace().frame_unwinders, name_re, flag
)
for objfile in gdb.objfiles():
if locus_re.match(objfile.filename):
total += do_enable_unwinder1(objfile.frame_unwinders, name_re, flag)
if total > 0:
gdb.invalidate_cached_frames()
print(
"%d unwinder%s %s"
% (total, "" if total == 1 else "s", "enabled" if flag else "disabled")
)
class EnableUnwinder(gdb.Command):
"""GDB command to enable unwinders.
Usage: enable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
LOCUS-REGEXP is a regular expression specifying the unwinders to
enable. It can 'global', 'progspace', or the name of an objfile
within that progspace.
NAME_REGEXP is a regular expression to filter unwinder names. If
this omitted for a specified locus, then all registered unwinders
in the locus are affected."""
def __init__(self):
super(EnableUnwinder, self).__init__("enable unwinder", gdb.COMMAND_STACK)
def invoke(self, arg, from_tty):
"""GDB calls this to perform the command."""
do_enable_unwinder(arg, True)
class DisableUnwinder(gdb.Command):
"""GDB command to disable the specified unwinder.
Usage: disable unwinder [LOCUS-REGEXP [NAME-REGEXP]]
LOCUS-REGEXP is a regular expression specifying the unwinders to
disable. It can 'global', 'progspace', or the name of an objfile
within that progspace.
NAME_REGEXP is a regular expression to filter unwinder names. If
this omitted for a specified locus, then all registered unwinders
in the locus are affected."""
def __init__(self):
super(DisableUnwinder, self).__init__("disable unwinder", gdb.COMMAND_STACK)
def invoke(self, arg, from_tty):
"""GDB calls this to perform the command."""
do_enable_unwinder(arg, False)
def register_unwinder_commands():
"""Installs the unwinder commands."""
InfoUnwinder()
EnableUnwinder()
DisableUnwinder()
register_unwinder_commands()