mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-08 16:43:19 +00:00
"pre-commit run --all" shows some flake8 warnings coming from a recent patch. There was no real bug here, but this fix silences the warnings.
736 lines
26 KiB
Python
736 lines
26 KiB
Python
# Copyright (C) 2010-2025 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 os
|
|
import signal
|
|
import sys
|
|
import threading
|
|
import traceback
|
|
from contextlib import contextmanager
|
|
from importlib import reload
|
|
|
|
# The star import imports _gdb names. When the names are used locally, they
|
|
# trigger F405 warnings unless added to the explicit import list.
|
|
# Note that two indicators are needed here to silence flake8.
|
|
from _gdb import * # noqa: F401,F403
|
|
from _gdb import (
|
|
COMMAND_NONE,
|
|
INTENSITY_BOLD,
|
|
INTENSITY_DIM,
|
|
INTENSITY_NORMAL,
|
|
PARAM_COLOR,
|
|
PARAM_ENUM,
|
|
STDERR,
|
|
STDOUT,
|
|
Color,
|
|
Command,
|
|
Parameter,
|
|
Style,
|
|
execute,
|
|
flush,
|
|
parameter,
|
|
selected_inferior,
|
|
write,
|
|
)
|
|
|
|
# isort: split
|
|
|
|
# Historically, gdb.events was always available, so ensure it's
|
|
# still available without an explicit import.
|
|
import _gdbevents as events
|
|
|
|
sys.modules["gdb.events"] = events
|
|
|
|
|
|
class _GdbFile(object):
|
|
# These two are needed in Python 3
|
|
encoding = "UTF-8"
|
|
errors = "strict"
|
|
|
|
def __init__(self, stream):
|
|
self.stream = stream
|
|
|
|
def close(self):
|
|
# Do nothing.
|
|
return None
|
|
|
|
def isatty(self):
|
|
return False
|
|
|
|
def writelines(self, iterable):
|
|
for line in iterable:
|
|
self.write(line)
|
|
|
|
def flush(self):
|
|
flush(stream=self.stream)
|
|
|
|
def write(self, s):
|
|
write(s, stream=self.stream)
|
|
|
|
|
|
sys.stdout = _GdbFile(STDOUT)
|
|
sys.stderr = _GdbFile(STDERR)
|
|
|
|
# Default prompt hook does nothing.
|
|
prompt_hook = None
|
|
|
|
# Ensure that sys.argv is set to something.
|
|
# We do not use PySys_SetArgvEx because it did not appear until 2.6.6.
|
|
sys.argv = [""]
|
|
|
|
# Initial pretty printers.
|
|
pretty_printers = []
|
|
|
|
# Initial type printers.
|
|
type_printers = []
|
|
# Initial xmethod matchers.
|
|
xmethods = []
|
|
# Initial frame filters.
|
|
frame_filters = {}
|
|
# Initial frame unwinders.
|
|
frame_unwinders = []
|
|
# The missing file handlers. Each item is a tuple with the form
|
|
# (TYPE, HANDLER) where TYPE is a string either 'debug' or 'objfile'.
|
|
missing_file_handlers = []
|
|
|
|
|
|
def _execute_unwinders(pending_frame):
|
|
"""Internal function called from GDB to execute all unwinders.
|
|
|
|
Runs each currently enabled unwinder until it finds the one that
|
|
can unwind given frame.
|
|
|
|
Arguments:
|
|
pending_frame: gdb.PendingFrame instance.
|
|
|
|
Returns:
|
|
Tuple with:
|
|
|
|
[0] gdb.UnwindInfo instance
|
|
[1] Name of unwinder that claimed the frame (type `str`)
|
|
|
|
or None, if no unwinder has claimed the frame.
|
|
"""
|
|
for objfile in objfiles():
|
|
for unwinder in objfile.frame_unwinders:
|
|
if unwinder.enabled:
|
|
unwind_info = unwinder(pending_frame)
|
|
if unwind_info is not None:
|
|
return (unwind_info, unwinder.name)
|
|
|
|
for unwinder in current_progspace().frame_unwinders:
|
|
if unwinder.enabled:
|
|
unwind_info = unwinder(pending_frame)
|
|
if unwind_info is not None:
|
|
return (unwind_info, unwinder.name)
|
|
|
|
for unwinder in frame_unwinders:
|
|
if unwinder.enabled:
|
|
unwind_info = unwinder(pending_frame)
|
|
if unwind_info is not None:
|
|
return (unwind_info, unwinder.name)
|
|
|
|
return None
|
|
|
|
|
|
# Convenience variable to GDB's python directory
|
|
PYTHONDIR = os.path.dirname(os.path.dirname(__file__))
|
|
|
|
# Auto-load all functions/commands.
|
|
|
|
# Packages to auto-load.
|
|
|
|
packages = ["function", "command", "printer"]
|
|
|
|
# pkgutil.iter_modules is not available prior to Python 2.6. Instead,
|
|
# manually iterate the list, collating the Python files in each module
|
|
# path. Construct the module name, and import.
|
|
|
|
|
|
def _auto_load_packages():
|
|
for package in packages:
|
|
location = os.path.join(os.path.dirname(__file__), package)
|
|
if os.path.exists(location):
|
|
py_files = filter(
|
|
lambda x: x.endswith(".py") and x != "__init__.py", os.listdir(location)
|
|
)
|
|
|
|
for py_file in py_files:
|
|
# Construct from foo.py, gdb.module.foo
|
|
modname = "%s.%s.%s" % (__name__, package, py_file[:-3])
|
|
try:
|
|
if modname in sys.modules:
|
|
# reload modules with duplicate names
|
|
reload(__import__(modname))
|
|
else:
|
|
__import__(modname)
|
|
except Exception:
|
|
sys.stderr.write(traceback.format_exc() + "\n")
|
|
|
|
|
|
_auto_load_packages()
|
|
|
|
|
|
def GdbSetPythonDirectory(dir):
|
|
"""Update sys.path, reload gdb and auto-load packages."""
|
|
global PYTHONDIR
|
|
|
|
try:
|
|
sys.path.remove(PYTHONDIR)
|
|
except ValueError:
|
|
pass
|
|
sys.path.insert(0, dir)
|
|
|
|
PYTHONDIR = dir
|
|
|
|
# note that reload overwrites the gdb module without deleting existing
|
|
# attributes
|
|
reload(__import__(__name__))
|
|
_auto_load_packages()
|
|
|
|
|
|
def current_progspace():
|
|
"Return the current Progspace."
|
|
return selected_inferior().progspace
|
|
|
|
|
|
def objfiles():
|
|
"Return a sequence of the current program space's objfiles."
|
|
return current_progspace().objfiles()
|
|
|
|
|
|
def solib_name(addr):
|
|
"""solib_name (Long) -> String.\n\
|
|
Return the name of the shared library holding a given address, or None."""
|
|
return current_progspace().solib_name(addr)
|
|
|
|
|
|
def block_for_pc(pc):
|
|
"Return the block containing the given pc value, or None."
|
|
return current_progspace().block_for_pc(pc)
|
|
|
|
|
|
def find_pc_line(pc):
|
|
"""find_pc_line (pc) -> Symtab_and_line.
|
|
Return the gdb.Symtab_and_line object corresponding to the pc value."""
|
|
return current_progspace().find_pc_line(pc)
|
|
|
|
|
|
def set_parameter(name, value):
|
|
"""Set the GDB parameter NAME to VALUE."""
|
|
# Handle the specific cases of None and booleans here, because
|
|
# gdb.parameter can return them, but they can't be passed to 'set'
|
|
# this way.
|
|
if value is None:
|
|
value = "unlimited"
|
|
elif isinstance(value, bool):
|
|
if value:
|
|
value = "on"
|
|
else:
|
|
value = "off"
|
|
execute("set " + name + " " + str(value), to_string=True)
|
|
|
|
|
|
@contextmanager
|
|
def with_parameter(name, value):
|
|
"""Temporarily set the GDB parameter NAME to VALUE.
|
|
Note that this is a context manager."""
|
|
old_value = parameter(name)
|
|
set_parameter(name, value)
|
|
try:
|
|
# Nothing that useful to return.
|
|
yield None
|
|
finally:
|
|
set_parameter(name, old_value)
|
|
|
|
|
|
@contextmanager
|
|
def blocked_signals():
|
|
"""A helper function that blocks and unblocks signals."""
|
|
if not hasattr(signal, "pthread_sigmask"):
|
|
yield
|
|
return
|
|
|
|
to_block = {signal.SIGCHLD, signal.SIGINT, signal.SIGALRM, signal.SIGWINCH}
|
|
old_mask = signal.pthread_sigmask(signal.SIG_BLOCK, to_block)
|
|
try:
|
|
yield None
|
|
finally:
|
|
signal.pthread_sigmask(signal.SIG_SETMASK, old_mask)
|
|
|
|
|
|
class Thread(threading.Thread):
|
|
"""A GDB-specific wrapper around threading.Thread
|
|
|
|
This wrapper ensures that the new thread blocks any signals that
|
|
must be delivered on GDB's main thread."""
|
|
|
|
def start(self):
|
|
# GDB requires that these be delivered to the main thread. We
|
|
# do this here to avoid any possible race with the creation of
|
|
# the new thread. The thread mask is inherited by new
|
|
# threads.
|
|
with blocked_signals():
|
|
super().start()
|
|
|
|
|
|
def _filter_missing_file_handlers(handlers, handler_type):
|
|
"""Each list of missing file handlers is a list of tuples, the first
|
|
item in the tuple is a string either 'debug' or 'objfile' to
|
|
indicate what type of handler it is. The second item in the tuple
|
|
is the actual handler object.
|
|
|
|
This function takes HANDLER_TYPE which is a string, either 'debug'
|
|
or 'objfile' and HANDLERS, a list of tuples. The function returns
|
|
an iterable over all of the handler objects (extracted from the
|
|
tuples) which match HANDLER_TYPE.
|
|
"""
|
|
|
|
return map(lambda t: t[1], filter(lambda t: t[0] == handler_type, handlers))
|
|
|
|
|
|
def _handle_missing_files(pspace, handler_type, cb):
|
|
"""Helper for _handle_missing_debuginfo and _handle_missing_objfile.
|
|
|
|
Arguments:
|
|
pspace: The gdb.Progspace in which we're operating. Used to
|
|
lookup program space specific handlers.
|
|
handler_type: A string, either 'debug' or 'objfile', this is the
|
|
type of handler we're looking for.
|
|
cb: A callback which takes a handler and returns the result of
|
|
calling the handler.
|
|
|
|
Returns:
|
|
None: No suitable file could be found.
|
|
False: A handler has decided that the requested file cannot be
|
|
found, and no further searching should be done.
|
|
True: The file has been found and installed in a location
|
|
where GDB would normally look for it. GDB should
|
|
repeat its lookup process, the file should now be in
|
|
place.
|
|
A string: This is the filename of where the missing file can
|
|
be found.
|
|
"""
|
|
|
|
for handler in _filter_missing_file_handlers(
|
|
pspace.missing_file_handlers, handler_type
|
|
):
|
|
if handler.enabled:
|
|
result = cb(handler)
|
|
if result is not None:
|
|
return result
|
|
|
|
for handler in _filter_missing_file_handlers(missing_file_handlers, handler_type):
|
|
if handler.enabled:
|
|
result = cb(handler)
|
|
if result is not None:
|
|
return result
|
|
|
|
return None
|
|
|
|
|
|
def _handle_missing_debuginfo(objfile):
|
|
"""Internal function called from GDB to execute missing debug
|
|
handlers.
|
|
|
|
Run each of the currently registered, and enabled missing debug
|
|
handler objects for the current program space and then from the
|
|
global list. Stop after the first handler that returns a result
|
|
other than None.
|
|
|
|
Arguments:
|
|
objfile: A gdb.Objfile for which GDB could not find any debug
|
|
information.
|
|
|
|
Returns:
|
|
None: No debug information could be found for objfile.
|
|
False: A handler has done all it can with objfile, but no
|
|
debug information could be found.
|
|
True: Debug information might have been installed by a
|
|
handler, GDB should check again.
|
|
A string: This is the filename of a file containing the
|
|
required debug information.
|
|
"""
|
|
|
|
pspace = objfile.progspace
|
|
|
|
return _handle_missing_files(pspace, "debug", lambda h: h(objfile))
|
|
|
|
|
|
def _handle_missing_objfile(pspace, buildid, filename):
|
|
"""Internal function called from GDB to execute missing objfile
|
|
handlers.
|
|
|
|
Run each of the currently registered, and enabled missing objfile
|
|
handler objects for the gdb.Progspace passed in as an argument,
|
|
and then from the global list. Stop after the first handler that
|
|
returns a result other than None.
|
|
|
|
Arguments:
|
|
pspace: A gdb.Progspace for which the missing objfile handlers
|
|
should be run. This is the program space in which an
|
|
objfile was found to be missing.
|
|
buildid: A string containing the build-id we're looking for.
|
|
filename: The filename of the file GDB tried to find but
|
|
couldn't. This is not where the file should be
|
|
placed if found, in fact, this file might already
|
|
exist on disk but have the wrong build-id. This is
|
|
mostly provided in order to be used in messages to
|
|
the user.
|
|
|
|
Returns:
|
|
None: No objfile could be found for this build-id.
|
|
False: A handler has done all it can with for this build-id,
|
|
but no objfile could be found.
|
|
True: An objfile might have been installed by a handler, GDB
|
|
should check again. The only place GDB checks is within
|
|
the .build-id sub-directory within the
|
|
debug-file-directory. If the required file was not
|
|
installed there then GDB will not find it.
|
|
A string: This is the filename of a file containing the
|
|
missing objfile.
|
|
"""
|
|
|
|
return _handle_missing_files(
|
|
pspace, "objfile", lambda h: h(pspace, buildid, filename)
|
|
)
|
|
|
|
|
|
class ParameterPrefix:
|
|
# A wrapper around gdb.Command for creating set/show prefixes.
|
|
#
|
|
# When creating a gdb.Parameter sub-classes, it is sometimes necessary
|
|
# to first create a gdb.Command object in order to create the needed
|
|
# command prefix. However, for parameters, we actually need two
|
|
# prefixes, a 'set' prefix, and a 'show' prefix. With this helper
|
|
# class, a single instance of this class will create both prefixes at
|
|
# once.
|
|
#
|
|
# It is important that this class-level documentation not be a __doc__
|
|
# string. Users are expected to sub-class this ParameterPrefix class
|
|
# and add their own documentation. If they don't, then GDB will
|
|
# generate a suitable doc string. But, if this (parent) class has a
|
|
# __doc__ string of its own, then sub-classes will inherit that __doc__
|
|
# string, and GDB will not understand that it needs to generate one.
|
|
|
|
class _PrefixCommand(Command):
|
|
"""A gdb.Command used to implement both the set and show prefixes.
|
|
|
|
This documentation string is not used as the prefix command
|
|
documentation as it is overridden in the __init__ method below."""
|
|
|
|
# This private method is connected to the 'invoke' attribute within
|
|
# this _PrefixCommand object if the containing ParameterPrefix
|
|
# object has an invoke_set or invoke_show method.
|
|
#
|
|
# This method records within self.__delegate which _PrefixCommand
|
|
# object is currently active, and then calls the correct invoke
|
|
# method on the delegat object (the ParameterPrefix sub-class
|
|
# object).
|
|
#
|
|
# Recording the currently active _PrefixCommand object is important;
|
|
# if from the invoke method the user calls dont_repeat, then this is
|
|
# forwarded to the currently active _PrefixCommand object.
|
|
def __invoke(self, args, from_tty):
|
|
|
|
# A helper class for use as part of a Python 'with' block.
|
|
# Records which gdb.Command object is currently running its
|
|
# invoke method.
|
|
class MarkActiveCallback:
|
|
# The CMD is a _PrefixCommand object, and the DELEGATE is
|
|
# the ParameterPrefix class, or sub-class object. At this
|
|
# point we simple record both of these within the
|
|
# MarkActiveCallback object.
|
|
def __init__(self, cmd, delegate):
|
|
self.__cmd = cmd
|
|
self.__delegate = delegate
|
|
|
|
# Record the currently active _PrefixCommand object within
|
|
# the outer ParameterPrefix sub-class object.
|
|
def __enter__(self):
|
|
self.__delegate.active_prefix = self.__cmd
|
|
|
|
# Once the invoke method has completed, then clear the
|
|
# _PrefixCommand object that was stored into the outer
|
|
# ParameterPrefix sub-class object.
|
|
def __exit__(self, exception_type, exception_value, traceback):
|
|
self.__delegate.active_prefix = None
|
|
|
|
# The self.__cb attribute is set when the _PrefixCommand object
|
|
# is created, and is either invoke_set or invoke_show within the
|
|
# ParameterPrefix sub-class object.
|
|
assert callable(self.__cb)
|
|
|
|
# Record the currently active _PrefixCommand object within the
|
|
# ParameterPrefix sub-class object, then call the relevant
|
|
# invoke method within the ParameterPrefix sub-class object.
|
|
with MarkActiveCallback(self, self.__delegate):
|
|
self.__cb(args, from_tty)
|
|
|
|
@staticmethod
|
|
def __find_callback(delegate, mode):
|
|
"""The MODE is either 'set' or 'show'. Look for an invoke_MODE method
|
|
on DELEGATE, if a suitable method is found, then return it, otherwise,
|
|
return None.
|
|
"""
|
|
cb = getattr(delegate, "invoke_" + mode, None)
|
|
if callable(cb):
|
|
return cb
|
|
return None
|
|
|
|
def __init__(self, mode, name, cmd_class, delegate, doc=None):
|
|
"""Setup this gdb.Command. Mode is a string, either 'set' or 'show'.
|
|
NAME is the name for this prefix command, that is, the
|
|
words that appear after both 'set' and 'show' in the
|
|
command name. CMD_CLASS is the usual enum. And DELEGATE
|
|
is the gdb.ParameterPrefix object this prefix is part of.
|
|
"""
|
|
assert mode == "set" or mode == "show"
|
|
if doc is None:
|
|
self.__doc__ = delegate.__doc__
|
|
else:
|
|
self.__doc__ = doc
|
|
self.__cb = self.__find_callback(delegate, mode)
|
|
self.__delegate = delegate
|
|
if self.__cb is not None:
|
|
self.invoke = self.__invoke
|
|
super().__init__(mode + " " + name, cmd_class, prefix=True)
|
|
|
|
def __init__(self, name, cmd_class, doc=None):
|
|
"""Create a _PrefixCommand for both the set and show prefix commands.
|
|
NAME is the command name without either the leading 'set ' or
|
|
'show ' strings, and CMD_CLASS is the usual enum value.
|
|
"""
|
|
self.active_prefix = None
|
|
self._set_prefix_cmd = self._PrefixCommand("set", name, cmd_class, self, doc)
|
|
self._show_prefix_cmd = self._PrefixCommand("show", name, cmd_class, self, doc)
|
|
|
|
# When called from within an invoke method the self.active_prefix
|
|
# attribute should be set to a gdb.Command sub-class (a _PrefixCommand
|
|
# object, see above). Forward the dont_repeat call to this object to
|
|
# register the actual command as none repeating.
|
|
def dont_repeat(self):
|
|
if self.active_prefix is not None:
|
|
self.active_prefix.dont_repeat()
|
|
|
|
|
|
class StyleParameterSet:
|
|
"""Create new style parameters.
|
|
|
|
A style parameter is a set of parameters that start with 'set style ...'
|
|
and 'show style ...'. For example 'filename' is a style parameter, and
|
|
'disassembler symbol' is another style parameter.
|
|
|
|
The name of the style parameter is really a prefix command. Under this
|
|
we must have two commands 'foreground' and 'background', which are color
|
|
parameters. A third, optional command 'intensity', is an enum with
|
|
values 'normal', 'bold', and 'dim'.
|
|
|
|
A StyleParameterSet is initialised with a name, e.g. 'filename' or
|
|
'disassembler symbol'. The StyleParameterSet creates the prefix
|
|
commands in the 'set style' and 'show style' name space, and then adds
|
|
the 'foreground', 'background', and optionally, the 'intensity'
|
|
commands.
|
|
|
|
If you want a whole new style group, similar to 'disassembler',
|
|
then you need to add this yourself first, then StyleParameterSet
|
|
can be used to create styles within the new prefix group.
|
|
|
|
The 'value' attribute on this object can be used to get and set a
|
|
gdb.Style object which controls all aspects of this style.
|
|
|
|
For readability, the alias 'style' is the same as 'value'.
|
|
"""
|
|
|
|
def __init__(self, name, add_intensity=True, doc=None):
|
|
# The STYLE_NAME is something like 'filename' is 'set style
|
|
# filename ...', and PARAM_NAME is one of 'foreground',
|
|
# 'background', or 'intensity'. The DESC_TEXT is the long
|
|
# form used in help text, like 'foreground color' or 'display
|
|
# intensity'. The DEFAULT_VALUE is used to set the SELF.value
|
|
# attribute. And PARAM_TYPE is a gdb.PARAM_* constant. The
|
|
# ARGS is used for gdb.PARAM_ENUM, which ARGS should be the
|
|
# enum value list.
|
|
class style_parameter(Parameter):
|
|
def __init__(
|
|
self,
|
|
style_name,
|
|
parent_obj,
|
|
param_name,
|
|
desc_text,
|
|
default_value,
|
|
param_type,
|
|
*args
|
|
):
|
|
# Setup documentation must be done before calling
|
|
# parent's __init__ method, as the __init__ reads (and
|
|
# copies) these values.
|
|
self.show_doc = "Show the " + desc_text + " for this property."
|
|
self.set_doc = "Set the " + desc_text + " for this property."
|
|
self.__doc__ = ""
|
|
|
|
# Call the parent's __init__ method to actually create
|
|
# the parameter.
|
|
super().__init__(
|
|
"style " + style_name + " " + param_name,
|
|
COMMAND_NONE,
|
|
param_type,
|
|
*args
|
|
)
|
|
|
|
# Store information we need in other methods.
|
|
self._style_name = style_name
|
|
self._desc_text = desc_text
|
|
self._parent = parent_obj
|
|
|
|
# Finally, setup the default value.
|
|
self.value = default_value
|
|
|
|
# Return the 'show style <style-name> <attribute>' string,
|
|
# which has styling applied.
|
|
def get_show_string(self, value):
|
|
s = self._parent.style
|
|
return (
|
|
"The "
|
|
+ s.apply('"' + self._style_name + '" style')
|
|
+ " "
|
|
+ self._desc_text
|
|
+ " is: "
|
|
+ value
|
|
)
|
|
|
|
class style_foreground_parameter(style_parameter):
|
|
def __init__(self, name, parent):
|
|
super().__init__(
|
|
name,
|
|
parent,
|
|
"foreground",
|
|
"foreground color",
|
|
Color(),
|
|
PARAM_COLOR,
|
|
)
|
|
|
|
class style_background_parameter(style_parameter):
|
|
def __init__(self, name, parent):
|
|
super().__init__(
|
|
name,
|
|
parent,
|
|
"background",
|
|
"background color",
|
|
Color(),
|
|
PARAM_COLOR,
|
|
)
|
|
|
|
class style_intensity_parameter(style_parameter):
|
|
def __init__(self, name, parent):
|
|
super().__init__(
|
|
name,
|
|
parent,
|
|
"intensity",
|
|
"display intensity",
|
|
"normal",
|
|
PARAM_ENUM,
|
|
["normal", "bold", "dim"],
|
|
)
|
|
|
|
if doc is None:
|
|
doc = (
|
|
"The "
|
|
+ name
|
|
+ " display styling.\nConfigure "
|
|
+ name
|
|
+ " colors and display intensity."
|
|
)
|
|
|
|
ParameterPrefix("style " + name, COMMAND_NONE, doc)
|
|
self._foreground = style_foreground_parameter(name, self)
|
|
self._background = style_background_parameter(name, self)
|
|
if add_intensity:
|
|
self._intensity = style_intensity_parameter(name, self)
|
|
self._name = name
|
|
self._style = None
|
|
|
|
@property
|
|
def value(self):
|
|
"""Return the gdb.Style object for this parameter set."""
|
|
if self._style is None:
|
|
self._style = Style(self._name)
|
|
return self._style
|
|
|
|
@property
|
|
def style(self):
|
|
"""Return the gdb.Style object for this parameter set.
|
|
|
|
This is an alias for self.value."""
|
|
return self.value
|
|
|
|
@value.setter
|
|
def value(self, new_value):
|
|
"""Set this parameter set to NEW_VALUE, a gdb.Style object.
|
|
|
|
The attributes of NEW_VALUE are used to update the current settings
|
|
of this parameter set. If this parameter set was created without
|
|
an intensity setting, then the intensity of NEW_VALUE is ignored."""
|
|
if not isinstance(new_value, Style):
|
|
raise TypeError("value must be gdb.Style, not %s" % type(new_value))
|
|
self._foreground.value = new_value.foreground
|
|
self._background.value = new_value.background
|
|
if hasattr(self, "_intensity"):
|
|
intensity_value = new_value.intensity
|
|
if intensity_value == INTENSITY_BOLD:
|
|
intensity_string = "bold"
|
|
elif intensity_value == INTENSITY_DIM:
|
|
intensity_string = "dim"
|
|
elif intensity_value == INTENSITY_NORMAL:
|
|
intensity_string = "normal"
|
|
else:
|
|
raise ValueError(
|
|
"unknown intensity value %d from Style" % intensity_value
|
|
)
|
|
|
|
self._intensity.value = intensity_string
|
|
|
|
@style.setter
|
|
def style(self, new_value):
|
|
"""Set this parameter set to NEW_VALUE, a gdb.Style object.
|
|
|
|
This is an alias for self.value."""
|
|
self.value = new_value
|
|
|
|
def apply(self, *args, **kwargs):
|
|
"""Apply this style to the arguments.
|
|
|
|
Forwards all arguments to self.style.apply(). The arguments should be a string,
|
|
to which this style is applied. This function returns the same string with
|
|
escape sequences added to apply this style.
|
|
|
|
If styling is globally disabled ('set style enabled off') then no escape sequences
|
|
will be added, the input string is returned."""
|
|
return self.style.apply(*args, **kwargs)
|
|
|
|
def __repr__(self):
|
|
"""A string representation of SELF."""
|
|
|
|
def full_typename(obj):
|
|
module = type(obj).__module__
|
|
qualname = type(obj).__qualname__
|
|
|
|
if module is None or module == "builtins":
|
|
return qualname
|
|
else:
|
|
return module + "." + qualname
|
|
|
|
return "<" + full_typename(self) + " name='" + self._name + "'>"
|