mirror of
https://github.com/tromey/gdb-gui.git
synced 2025-07-20 20:41:28 +02:00
Run black
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
import sys
|
import sys
|
||||||
sys.path.append('HERE')
|
|
||||||
|
sys.path.append("HERE")
|
||||||
import gui.commands
|
import gui.commands
|
||||||
|
@@ -24,18 +24,15 @@ bugs = {
|
|||||||
15620: """Your gdb doesn't have a "new breakpoint" event.
|
15620: """Your gdb doesn't have a "new breakpoint" event.
|
||||||
This means that the source windows will not show you where
|
This means that the source windows will not show you where
|
||||||
breakpoints have been set.""",
|
breakpoints have been set.""",
|
||||||
|
|
||||||
13598: """Your gdb doesn't have a "before prompt" event.
|
13598: """Your gdb doesn't have a "before prompt" event.
|
||||||
This means that various windows won't be able to react to
|
This means that various windows won't be able to react to
|
||||||
commands like "up" or "down".""",
|
commands like "up" or "down".""",
|
||||||
|
|
||||||
18385: """Your gdb doesn't expose locations on a gdb.Breakpoint.
|
18385: """Your gdb doesn't expose locations on a gdb.Breakpoint.
|
||||||
This can be worked around, but maybe not always reliably.
|
This can be worked around, but maybe not always reliably.
|
||||||
This means that sometimes breakpoints won't display in source windows.""",
|
This means that sometimes breakpoints won't display in source windows.""",
|
||||||
|
|
||||||
18620: """Your gdb doesn't have a "breakpoint modified" event.
|
18620: """Your gdb doesn't have a "breakpoint modified" event.
|
||||||
This means that when a pending breakpoint is resolved, the GUI won't
|
This means that when a pending breakpoint is resolved, the GUI won't
|
||||||
be able to update to reflect that fact."""
|
be able to update to reflect that fact.""",
|
||||||
}
|
}
|
||||||
|
|
||||||
_warning = """See https://sourceware.org/bugzilla/show_bug.cgi?id=%s
|
_warning = """See https://sourceware.org/bugzilla/show_bug.cgi?id=%s
|
||||||
@@ -43,6 +40,7 @@ for more information."""
|
|||||||
|
|
||||||
_first_report = True
|
_first_report = True
|
||||||
|
|
||||||
|
|
||||||
def notify_bug(bugno):
|
def notify_bug(bugno):
|
||||||
if not gui.params.warn_missing.value:
|
if not gui.params.warn_missing.value:
|
||||||
return
|
return
|
||||||
|
@@ -22,6 +22,7 @@ import gui.adapt
|
|||||||
# destroyed.
|
# destroyed.
|
||||||
_breakpoint_source_map = {}
|
_breakpoint_source_map = {}
|
||||||
|
|
||||||
|
|
||||||
def _breakpoint_created(bp):
|
def _breakpoint_created(bp):
|
||||||
if bp.location is None:
|
if bp.location is None:
|
||||||
return
|
return
|
||||||
@@ -45,6 +46,7 @@ def _breakpoint_created(bp):
|
|||||||
else:
|
else:
|
||||||
_breakpoint_source_map[entry].add(bp.number)
|
_breakpoint_source_map[entry].add(bp.number)
|
||||||
|
|
||||||
|
|
||||||
def _breakpoint_deleted(bp):
|
def _breakpoint_deleted(bp):
|
||||||
num = bp.number
|
num = bp.number
|
||||||
for entry in _breakpoint_source_map:
|
for entry in _breakpoint_source_map:
|
||||||
@@ -53,25 +55,28 @@ def _breakpoint_deleted(bp):
|
|||||||
if len(_breakpoint_source_map[entry]) == 0:
|
if len(_breakpoint_source_map[entry]) == 0:
|
||||||
gui.events.location_changed.post(entry, False)
|
gui.events.location_changed.post(entry, False)
|
||||||
|
|
||||||
|
|
||||||
def _breakpoint_modified(bp):
|
def _breakpoint_modified(bp):
|
||||||
if bp.enabled:
|
if bp.enabled:
|
||||||
_breakpoint_created(bp)
|
_breakpoint_created(bp)
|
||||||
else:
|
else:
|
||||||
_breakpoint_deleted(bp)
|
_breakpoint_deleted(bp)
|
||||||
|
|
||||||
|
|
||||||
def any_breakpoint_at(filename, lineno):
|
def any_breakpoint_at(filename, lineno):
|
||||||
entry = (filename, lineno)
|
entry = (filename, lineno)
|
||||||
if entry not in _breakpoint_source_map:
|
if entry not in _breakpoint_source_map:
|
||||||
return False
|
return False
|
||||||
return len(_breakpoint_source_map[entry]) > 0
|
return len(_breakpoint_source_map[entry]) > 0
|
||||||
|
|
||||||
if not hasattr(gdb.events, 'breakpoint_created'):
|
|
||||||
|
if not hasattr(gdb.events, "breakpoint_created"):
|
||||||
gui.adapt.notify_bug(15620)
|
gui.adapt.notify_bug(15620)
|
||||||
else:
|
else:
|
||||||
gdb.events.breakpoint_created.connect(_breakpoint_created)
|
gdb.events.breakpoint_created.connect(_breakpoint_created)
|
||||||
gdb.events.breakpoint_deleted.connect(_breakpoint_deleted)
|
gdb.events.breakpoint_deleted.connect(_breakpoint_deleted)
|
||||||
|
|
||||||
if not hasattr(gdb.events, 'breakpoint_modified'):
|
if not hasattr(gdb.events, "breakpoint_modified"):
|
||||||
gui.adapt.notify_bug(18620)
|
gui.adapt.notify_bug(18620)
|
||||||
else:
|
else:
|
||||||
gdb.events.breakpoint_modified.connect(_breakpoint_modified)
|
gdb.events.breakpoint_modified.connect(_breakpoint_modified)
|
||||||
|
214
gui/commands.py
214
gui/commands.py
@@ -27,33 +27,33 @@ import gui.adapt
|
|||||||
import re
|
import re
|
||||||
from gui.startup import in_gtk_thread
|
from gui.startup import in_gtk_thread
|
||||||
|
|
||||||
|
|
||||||
class GuiCommand(gdb.Command):
|
class GuiCommand(gdb.Command):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiCommand, self).__init__('gui', gdb.COMMAND_SUPPORT,
|
super(GuiCommand, self).__init__("gui", gdb.COMMAND_SUPPORT, prefix=True)
|
||||||
prefix = True)
|
|
||||||
|
|
||||||
class GuiSourceCommand(gdb.Command):
|
class GuiSourceCommand(gdb.Command):
|
||||||
"""Create a new source window.
|
"""Create a new source window.
|
||||||
Usage: gui source
|
Usage: gui source
|
||||||
This creates a new source window in the GUI. Any number of source
|
This creates a new source window in the GUI. Any number of source
|
||||||
windows can be created."""
|
windows can be created."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiSourceCommand, self).__init__('gui source',
|
super(GuiSourceCommand, self).__init__("gui source", gdb.COMMAND_SUPPORT)
|
||||||
gdb.COMMAND_SUPPORT)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
self.dont_repeat()
|
self.dont_repeat()
|
||||||
gui.source.lru_handler.new_source_window()
|
gui.source.lru_handler.new_source_window()
|
||||||
|
|
||||||
|
|
||||||
class GuiStackCommand(gdb.Command):
|
class GuiStackCommand(gdb.Command):
|
||||||
"""Create a new stack window.
|
"""Create a new stack window.
|
||||||
Usage: gui stack
|
Usage: gui stack
|
||||||
This creates a stack window in the GUI if it does not already exist."""
|
This creates a stack window in the GUI if it does not already exist."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiStackCommand, self).__init__('gui stack',
|
super(GuiStackCommand, self).__init__("gui stack", gdb.COMMAND_SUPPORT)
|
||||||
gdb.COMMAND_SUPPORT)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
self.dont_repeat()
|
self.dont_repeat()
|
||||||
@@ -64,45 +64,45 @@ This creates a stack window in the GUI if it does not already exist."""
|
|||||||
# or maybe even whatever 'bt' takes?
|
# or maybe even whatever 'bt' takes?
|
||||||
gui.stack.show_stack()
|
gui.stack.show_stack()
|
||||||
|
|
||||||
|
|
||||||
class GuiListCommand(gdb.Command):
|
class GuiListCommand(gdb.Command):
|
||||||
"""List some source code in a source window.
|
"""List some source code in a source window.
|
||||||
Usage: gui list LINESPEC
|
Usage: gui list LINESPEC
|
||||||
This command uses LINESPEC to show some source code in a source
|
This command uses LINESPEC to show some source code in a source
|
||||||
window. If a source window is already available, the source is
|
window. If a source window is already available, the source is
|
||||||
displayed there. Otherwise, a new source window is made.
|
displayed there. Otherwise, a new source window is made.
|
||||||
LINESPEC is a line specification of the form given to 'break'."""
|
LINESPEC is a line specification of the form given to 'break'."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiListCommand, self).__init__('gui list',
|
super(GuiListCommand, self).__init__("gui list", gdb.COMMAND_SUPPORT)
|
||||||
gdb.COMMAND_SUPPORT)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
self.dont_repeat()
|
self.dont_repeat()
|
||||||
(extra, sals) = gdb.decode_line(arg)
|
(extra, sals) = gdb.decode_line(arg)
|
||||||
if extra is not None:
|
if extra is not None:
|
||||||
raise gdb.GdbError('unrecognized junk at end of command: ' + extra)
|
raise gdb.GdbError("unrecognized junk at end of command: " + extra)
|
||||||
if sals is None:
|
if sals is None:
|
||||||
raise gdb.GdbError('not found')
|
raise gdb.GdbError("not found")
|
||||||
if len(sals) > 1:
|
if len(sals) > 1:
|
||||||
print("Ambiguous linespec, only showing first result")
|
print("Ambiguous linespec, only showing first result")
|
||||||
sal = sals[0]
|
sal = sals[0]
|
||||||
if sal.symtab is None or sal.symtab.filename is None:
|
if sal.symtab is None or sal.symtab.filename is None:
|
||||||
raise gdb.GdbError('could not find file for symbol')
|
raise gdb.GdbError("could not find file for symbol")
|
||||||
gui.source.lru_handler.show_source_gdb(None, sal.symtab,
|
gui.source.lru_handler.show_source_gdb(
|
||||||
sal.symtab.fullname(),
|
None, sal.symtab, sal.symtab.fullname(), sal.line
|
||||||
sal.line)
|
)
|
||||||
|
|
||||||
|
|
||||||
class GuiShowCommand(gdb.Command):
|
class GuiShowCommand(gdb.Command):
|
||||||
"""Show the source for a symbol in a source window.
|
"""Show the source for a symbol in a source window.
|
||||||
Usage: gui show SYMBOL
|
Usage: gui show SYMBOL
|
||||||
This command looks for the definition of SYMBOL in the program and
|
This command looks for the definition of SYMBOL in the program and
|
||||||
shows its source location in a source window. If a source window is
|
shows its source location in a source window. If a source window is
|
||||||
already available, the source is displayed there. Otherwise, a new
|
already available, the source is displayed there. Otherwise, a new
|
||||||
source window is made."""
|
source window is made."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiShowCommand, self).__init__('gui show',
|
super(GuiShowCommand, self).__init__("gui show", gdb.COMMAND_SUPPORT)
|
||||||
gdb.COMMAND_SUPPORT)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
self.dont_repeat()
|
self.dont_repeat()
|
||||||
@@ -113,101 +113,110 @@ source window is made."""
|
|||||||
raise
|
raise
|
||||||
symbol = gdb.lookup_global_symbol(arg)
|
symbol = gdb.lookup_global_symbol(arg)
|
||||||
if symbol is None:
|
if symbol is None:
|
||||||
raise gdb.GdbError('symbol ' + arg + ' not found')
|
raise gdb.GdbError("symbol " + arg + " not found")
|
||||||
if symbol.symtab is None or symbol.symtab.filename is None:
|
if symbol.symtab is None or symbol.symtab.filename is None:
|
||||||
raise gdb.GdbError('symbol ' + arg
|
raise gdb.GdbError(
|
||||||
+ ' does not seem to have an associated file')
|
"symbol " + arg + " does not seem to have an associated file"
|
||||||
gui.source.lru_handler.show_source_gdb(None, symbol.symtab,
|
)
|
||||||
symbol.symtab.fullname(),
|
gui.source.lru_handler.show_source_gdb(
|
||||||
symbol.line)
|
None, symbol.symtab, symbol.symtab.fullname(), symbol.line
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class GuiLogWindowCommand(gdb.Command):
|
class GuiLogWindowCommand(gdb.Command):
|
||||||
"""Create a new log window.
|
"""Create a new log window.
|
||||||
Usage: gui log
|
Usage: gui log
|
||||||
This creates a new "log" window in the GUI. A log window is used
|
This creates a new "log" window in the GUI. A log window is used
|
||||||
to display output from "gui print", "gui printf", "gui output",
|
to display output from "gui print", "gui printf", "gui output",
|
||||||
and "gui dprintf".
|
and "gui dprintf".
|
||||||
|
|
||||||
Multiple log windows can be created and output can be directed to
|
Multiple log windows can be created and output can be directed to
|
||||||
a given instance using the "@" syntax, like:
|
a given instance using the "@" syntax, like:
|
||||||
|
|
||||||
gui print @5 variable"""
|
gui print @5 variable"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiLogWindowCommand, self).__init__('gui log',
|
super(GuiLogWindowCommand, self).__init__("gui log", gdb.COMMAND_SUPPORT)
|
||||||
gdb.COMMAND_SUPPORT)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
self.dont_repeat()
|
self.dont_repeat()
|
||||||
window = gui.logwindow.LogWindow()
|
window = gui.logwindow.LogWindow()
|
||||||
print("Created log window %d; now the default" % window.number)
|
print("Created log window %d; now the default" % window.number)
|
||||||
|
|
||||||
|
|
||||||
class GuiPrintBase(gdb.Command):
|
class GuiPrintBase(gdb.Command):
|
||||||
def __init__(self, command):
|
def __init__(self, command):
|
||||||
super(GuiPrintBase, self).__init__('gui ' + command,
|
super(GuiPrintBase, self).__init__("gui " + command, gdb.COMMAND_SUPPORT)
|
||||||
gdb.COMMAND_SUPPORT)
|
|
||||||
self.command = command
|
self.command = command
|
||||||
|
|
||||||
# Given ARG, return a pair (WINDOW, NEW_ARG).
|
# Given ARG, return a pair (WINDOW, NEW_ARG).
|
||||||
def _parse_arg(self, arg, do_default = True):
|
def _parse_arg(self, arg, do_default=True):
|
||||||
arg = arg.strip()
|
arg = arg.strip()
|
||||||
match = re.match('@(\\d+)\\s+(.*)$', arg)
|
match = re.match("@(\\d+)\\s+(.*)$", arg)
|
||||||
if match is not None:
|
if match is not None:
|
||||||
winno = int(match.group(1))
|
winno = int(match.group(1))
|
||||||
arg = match.group(2)
|
arg = match.group(2)
|
||||||
window = gui.toplevel.state.get(winno)
|
window = gui.toplevel.state.get(winno)
|
||||||
if window is None:
|
if window is None:
|
||||||
raise gdb.GdbError('could not find window %d' % winno)
|
raise gdb.GdbError("could not find window %d" % winno)
|
||||||
if not isinstance(window, gui.logwindow.LogWindow):
|
if not isinstance(window, gui.logwindow.LogWindow):
|
||||||
raise gdb.GdbError('window %d is not a log window' % winno)
|
raise gdb.GdbError("window %d is not a log window" % winno)
|
||||||
elif do_default:
|
elif do_default:
|
||||||
window = gui.logwindow.default_log_window
|
window = gui.logwindow.default_log_window
|
||||||
if window is None:
|
if window is None:
|
||||||
raise gdb.GdbError('no default log window')
|
raise gdb.GdbError("no default log window")
|
||||||
else:
|
else:
|
||||||
window = None
|
window = None
|
||||||
return (window, arg)
|
return (window, arg)
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
(window, arg) = self._parse_arg(arg)
|
(window, arg) = self._parse_arg(arg)
|
||||||
text = gdb.execute(self.command + ' ' + arg, from_tty, True)
|
text = gdb.execute(self.command + " " + arg, from_tty, True)
|
||||||
window.append(text)
|
window.append(text)
|
||||||
|
|
||||||
|
|
||||||
class GuiPrintCommand(GuiPrintBase):
|
class GuiPrintCommand(GuiPrintBase):
|
||||||
"""Print to a gui log window.
|
"""Print to a gui log window.
|
||||||
Usage: gui print [@N] ARGS
|
Usage: gui print [@N] ARGS
|
||||||
This is a wrapper for the "print" command that redirects its output
|
This is a wrapper for the "print" command that redirects its output
|
||||||
to a "gui log" window. If "@N" is given, then output goes to that
|
to a "gui log" window. If "@N" is given, then output goes to that
|
||||||
window; otherwise, output goes to the most recently created log window."""
|
window; otherwise, output goes to the most recently created log window."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiPrintCommand, self).__init__('print')
|
super(GuiPrintCommand, self).__init__("print")
|
||||||
|
|
||||||
|
|
||||||
class GuiOutputCommand(GuiPrintBase):
|
class GuiOutputCommand(GuiPrintBase):
|
||||||
"""Output to a gui log window.
|
"""Output to a gui log window.
|
||||||
Usage: gui output [@N] ARGS
|
Usage: gui output [@N] ARGS
|
||||||
This is a wrapper for the "output" command that redirects its output
|
This is a wrapper for the "output" command that redirects its output
|
||||||
to a "gui log" window. If "@N" is given, then output goes to that
|
to a "gui log" window. If "@N" is given, then output goes to that
|
||||||
window; otherwise, output goes to the most recently created log window."""
|
window; otherwise, output goes to the most recently created log window."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiOutputCommand, self).__init__('output')
|
super(GuiOutputCommand, self).__init__("output")
|
||||||
|
|
||||||
|
|
||||||
class GuiPrintfCommand(GuiPrintBase):
|
class GuiPrintfCommand(GuiPrintBase):
|
||||||
"""printf to a gui log window.
|
"""printf to a gui log window.
|
||||||
Usage: gui printf [@N] ARGS
|
Usage: gui printf [@N] ARGS
|
||||||
This is a wrapper for the "printf" command that redirects its output
|
This is a wrapper for the "printf" command that redirects its output
|
||||||
to a "gui log" window. If "@N" is given, then output goes to that
|
to a "gui log" window. If "@N" is given, then output goes to that
|
||||||
window; otherwise, output goes to the most recently created log window."""
|
window; otherwise, output goes to the most recently created log window."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiPrintfCommand, self).__init__('printf')
|
super(GuiPrintfCommand, self).__init__("printf")
|
||||||
|
|
||||||
|
|
||||||
class GuiDprintfCommand(GuiPrintBase):
|
class GuiDprintfCommand(GuiPrintBase):
|
||||||
"""dprintf to a gui log window.
|
"""dprintf to a gui log window.
|
||||||
Usage: gui dprintf [@N] ARGS
|
Usage: gui dprintf [@N] ARGS
|
||||||
This is a wrapper for the "dprintf" command that redirects its output
|
This is a wrapper for the "dprintf" command that redirects its output
|
||||||
to a "gui log" window. If "@N" is given, then output goes to that
|
to a "gui log" window. If "@N" is given, then output goes to that
|
||||||
window; otherwise, output goes to the most recently created log window."""
|
window; otherwise, output goes to the most recently created log window."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiDprintfCommand, self).__init__('dprintf')
|
super(GuiDprintfCommand, self).__init__("dprintf")
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
(window, arg) = self._parse_arg(arg, False)
|
(window, arg) = self._parse_arg(arg, False)
|
||||||
@@ -216,29 +225,29 @@ window; otherwise, output goes to the most recently created log window."""
|
|||||||
if arg is None:
|
if arg is None:
|
||||||
raise gdb.GdbError("no printf arguments to 'gui dprintf'")
|
raise gdb.GdbError("no printf arguments to 'gui dprintf'")
|
||||||
arg = arg.strip()
|
arg = arg.strip()
|
||||||
if not arg.startswith(','):
|
if not arg.startswith(","):
|
||||||
raise gdb.GdbError("comma expected after linespec")
|
raise gdb.GdbError("comma expected after linespec")
|
||||||
arg = arg[1:]
|
arg = arg[1:]
|
||||||
spec = arg[0 : -len(arg)]
|
spec = arg[0 : -len(arg)]
|
||||||
DPrintfBreakpoint(spec, window, arg)
|
DPrintfBreakpoint(spec, window, arg)
|
||||||
|
|
||||||
|
|
||||||
class GuiDisplayCommand(gdb.Command):
|
class GuiDisplayCommand(gdb.Command):
|
||||||
"""Create a new display window.
|
"""Create a new display window.
|
||||||
Usage: gui display [-diff] COMMAND
|
Usage: gui display [-diff] COMMAND
|
||||||
|
|
||||||
A display window runs a gdb command after operations that change the
|
A display window runs a gdb command after operations that change the
|
||||||
current frame or that cause the inferior to stop. If "-diff" is
|
current frame or that cause the inferior to stop. If "-diff" is
|
||||||
given, then every time the display is updated, changed lines are
|
given, then every time the display is updated, changed lines are
|
||||||
highlighted."""
|
highlighted."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(GuiDisplayCommand, self).__init__('gui display',
|
super(GuiDisplayCommand, self).__init__("gui display", gdb.COMMAND_SUPPORT)
|
||||||
gdb.COMMAND_SUPPORT)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
self.dont_repeat()
|
self.dont_repeat()
|
||||||
diff = False
|
diff = False
|
||||||
if arg.startswith('-diff '):
|
if arg.startswith("-diff "):
|
||||||
diff = True
|
diff = True
|
||||||
arg = arg[6:]
|
arg = arg[6:]
|
||||||
gui.display.DisplayWindow(arg, diff)
|
gui.display.DisplayWindow(arg, diff)
|
||||||
@@ -248,31 +257,31 @@ highlighted."""
|
|||||||
# https://sourceware.org/bugzilla/show_bug.cgi?id=13077
|
# https://sourceware.org/bugzilla/show_bug.cgi?id=13077
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class InfoWindowsCommand(gdb.Command):
|
class InfoWindowsCommand(gdb.Command):
|
||||||
"""List all the GUI windows.
|
"""List all the GUI windows.
|
||||||
Usage: info windows
|
Usage: info windows
|
||||||
This lists all the GUI windows.
|
This lists all the GUI windows.
|
||||||
Note that this should not be confused with "info win", which is
|
Note that this should not be confused with "info win", which is
|
||||||
part of the TUI."""
|
part of the TUI."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(InfoWindowsCommand, self).__init__('info windows',
|
super(InfoWindowsCommand, self).__init__("info windows", gdb.COMMAND_SUPPORT)
|
||||||
gdb.COMMAND_SUPPORT)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
self.dont_repeat()
|
self.dont_repeat()
|
||||||
gui.toplevel.state.display()
|
gui.toplevel.state.display()
|
||||||
|
|
||||||
|
|
||||||
class DeleteWindowsCommand(gdb.Command):
|
class DeleteWindowsCommand(gdb.Command):
|
||||||
"""Delete a GUI window.
|
"""Delete a GUI window.
|
||||||
Usage: delete window N
|
Usage: delete window N
|
||||||
Delete GUI window number N.
|
Delete GUI window number N.
|
||||||
A window's number appears in its title bar, and can also be
|
A window's number appears in its title bar, and can also be
|
||||||
found using "info windows"."""
|
found using "info windows"."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(DeleteWindowsCommand, self).__init__('delete window',
|
super(DeleteWindowsCommand, self).__init__("delete window", gdb.COMMAND_SUPPORT)
|
||||||
gdb.COMMAND_SUPPORT)
|
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
self.dont_repeat()
|
self.dont_repeat()
|
||||||
@@ -281,6 +290,7 @@ found using "info windows"."""
|
|||||||
if window is not None:
|
if window is not None:
|
||||||
window.destroy()
|
window.destroy()
|
||||||
|
|
||||||
|
|
||||||
GuiCommand()
|
GuiCommand()
|
||||||
GuiSourceCommand()
|
GuiSourceCommand()
|
||||||
GuiStackCommand()
|
GuiStackCommand()
|
||||||
@@ -304,7 +314,7 @@ class TestCommand(gdb.Command):
|
|||||||
your copy of gdb has some command-overriding support."""
|
your copy of gdb has some command-overriding support."""
|
||||||
|
|
||||||
def __init__(self, set_it):
|
def __init__(self, set_it):
|
||||||
super(TestCommand, self).__init__('maint gui-test', gdb.COMMAND_DATA)
|
super(TestCommand, self).__init__("maint gui-test", gdb.COMMAND_DATA)
|
||||||
self.set_it = set_it
|
self.set_it = set_it
|
||||||
|
|
||||||
def invoke(self, arg, from_tty):
|
def invoke(self, arg, from_tty):
|
||||||
@@ -317,13 +327,15 @@ class TestCommand(gdb.Command):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
TestCommand(True)
|
TestCommand(True)
|
||||||
TestCommand(False).invoke('', 0)
|
TestCommand(False).invoke("", 0)
|
||||||
|
|
||||||
# See framecache.py - we prefer the before_prompt event if it exists;
|
# See framecache.py - we prefer the before_prompt event if it exists;
|
||||||
# but otherwise try the overriding approach. Both of these rely on a
|
# but otherwise try the overriding approach. Both of these rely on a
|
||||||
# hacked gdb :-(
|
# hacked gdb :-(
|
||||||
if _can_override and not hasattr(gdb.events, 'before_prompt'):
|
if _can_override and not hasattr(gdb.events, "before_prompt"):
|
||||||
|
|
||||||
class Overrider(gdb.Command):
|
class Overrider(gdb.Command):
|
||||||
def __init__(self, name, event):
|
def __init__(self, name, event):
|
||||||
super(Overrider, self).__init__(name, gdb.COMMAND_DATA)
|
super(Overrider, self).__init__(name, gdb.COMMAND_DATA)
|
||||||
@@ -333,6 +345,6 @@ if _can_override and not hasattr(gdb.events, 'before_prompt'):
|
|||||||
super(Overrider, self).invoke(arg, from_tty)
|
super(Overrider, self).invoke(arg, from_tty)
|
||||||
self.event.post()
|
self.event.post()
|
||||||
|
|
||||||
Overrider('up', gui.events.frame_changed)
|
Overrider("up", gui.events.frame_changed)
|
||||||
Overrider('down', gui.events.frame_changed)
|
Overrider("down", gui.events.frame_changed)
|
||||||
Overrider('frame', gui.events.frame_changed)
|
Overrider("frame", gui.events.frame_changed)
|
||||||
|
@@ -27,38 +27,38 @@ from difflib import SequenceMatcher, Differ
|
|||||||
# FIXME: TO DO:
|
# FIXME: TO DO:
|
||||||
# * highlight the changes
|
# * highlight the changes
|
||||||
|
|
||||||
|
|
||||||
class DisplayWindow(gui.updatewindow.UpdateWindow):
|
class DisplayWindow(gui.updatewindow.UpdateWindow):
|
||||||
def __init__(self, command, diff = False):
|
def __init__(self, command, diff=False):
|
||||||
self.command = command
|
self.command = command
|
||||||
self.diff = diff
|
self.diff = diff
|
||||||
self.last_text = None
|
self.last_text = None
|
||||||
super(DisplayWindow, self).__init__('display')
|
super(DisplayWindow, self).__init__("display")
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def on_event(self):
|
def on_event(self):
|
||||||
try:
|
try:
|
||||||
text = gdb.execute(self.command, to_string = True)
|
text = gdb.execute(self.command, to_string=True)
|
||||||
except gdb.error as what:
|
except gdb.error as what:
|
||||||
text = str(what)
|
text = str(what)
|
||||||
gui.startup.send_to_gtk(lambda: self._update(text))
|
gui.startup.send_to_gtk(lambda: self._update(text))
|
||||||
|
|
||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def gtk_initialize(self):
|
def gtk_initialize(self):
|
||||||
builder = gui.startup.create_builder('logwindow.xml')
|
builder = gui.startup.create_builder("logwindow.xml")
|
||||||
builder.connect_signals(self)
|
builder.connect_signals(self)
|
||||||
|
|
||||||
self.window = builder.get_object('logwindow')
|
self.window = builder.get_object("logwindow")
|
||||||
self.view = builder.get_object('textview')
|
self.view = builder.get_object("textview")
|
||||||
self.view.modify_font(Pango.FontDescription('Fixed'))
|
self.view.modify_font(Pango.FontDescription("Fixed"))
|
||||||
|
|
||||||
self.buffer = builder.get_object('buffer')
|
self.buffer = builder.get_object("buffer")
|
||||||
|
|
||||||
if self.diff:
|
if self.diff:
|
||||||
self.tag = self.buffer.create_tag('new', foreground = 'red')
|
self.tag = self.buffer.create_tag("new", foreground="red")
|
||||||
|
|
||||||
def _update(self, text):
|
def _update(self, text):
|
||||||
self.buffer.delete(self.buffer.get_start_iter(),
|
self.buffer.delete(self.buffer.get_start_iter(), self.buffer.get_end_iter())
|
||||||
self.buffer.get_end_iter())
|
|
||||||
if self.diff:
|
if self.diff:
|
||||||
if self.last_text is None:
|
if self.last_text is None:
|
||||||
self.last_text = text.splitlines(1)
|
self.last_text = text.splitlines(1)
|
||||||
@@ -67,14 +67,13 @@ class DisplayWindow(gui.updatewindow.UpdateWindow):
|
|||||||
split = text.splitlines(1)
|
split = text.splitlines(1)
|
||||||
d = Differ()
|
d = Differ()
|
||||||
for line in d.compare(self.last_text, split):
|
for line in d.compare(self.last_text, split):
|
||||||
if line[0] == ' ':
|
if line[0] == " ":
|
||||||
self.buffer.insert(self.buffer.get_end_iter(),
|
self.buffer.insert(self.buffer.get_end_iter(), line[2:])
|
||||||
line[2:])
|
elif line[0] == "+":
|
||||||
elif line[0] == '+':
|
self.buffer.insert_with_tags(
|
||||||
self.buffer.insert_with_tags(self.buffer.get_end_iter(),
|
self.buffer.get_end_iter(), line[2:], self.tag
|
||||||
line[2:],
|
)
|
||||||
self.tag)
|
self.buffer.insert(self.buffer.get_end_iter(), "\n")
|
||||||
self.buffer.insert(self.buffer.get_end_iter(), '\n')
|
|
||||||
self.last_text = split
|
self.last_text = split
|
||||||
return
|
return
|
||||||
self.buffer.insert_at_cursor(text)
|
self.buffer.insert_at_cursor(text)
|
||||||
|
@@ -19,12 +19,13 @@ import gdb
|
|||||||
import gui.logwindow
|
import gui.logwindow
|
||||||
from gui.startup import in_gdb_thread
|
from gui.startup import in_gdb_thread
|
||||||
|
|
||||||
|
|
||||||
class DPrintfBreakpoint(gdb.Breakpoint):
|
class DPrintfBreakpoint(gdb.Breakpoint):
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def __init__(self, spec, window, arg):
|
def __init__(self, spec, window, arg):
|
||||||
super(DPrintfBreakpoint, self).__init__(spec, gdb.BP_BREAKPOINT)
|
super(DPrintfBreakpoint, self).__init__(spec, gdb.BP_BREAKPOINT)
|
||||||
self.window = window
|
self.window = window
|
||||||
self.command = 'printf ' + arg
|
self.command = "printf " + arg
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
|
|
||||||
class _Event(object):
|
class _Event(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.funcs = []
|
self.funcs = []
|
||||||
@@ -29,5 +30,6 @@ class _Event(object):
|
|||||||
for fun in self.funcs:
|
for fun in self.funcs:
|
||||||
fun(*args, **kwargs)
|
fun(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
frame_changed = _Event()
|
frame_changed = _Event()
|
||||||
location_changed = _Event()
|
location_changed = _Event()
|
||||||
|
@@ -22,6 +22,7 @@ from gui.startup import in_gdb_thread
|
|||||||
|
|
||||||
_last_selected_frame = None
|
_last_selected_frame = None
|
||||||
|
|
||||||
|
|
||||||
def check_frame():
|
def check_frame():
|
||||||
global _last_selected_frame
|
global _last_selected_frame
|
||||||
sel = None
|
sel = None
|
||||||
@@ -33,6 +34,7 @@ def check_frame():
|
|||||||
_last_selected_frame = sel
|
_last_selected_frame = sel
|
||||||
gui.events.frame_changed.post()
|
gui.events.frame_changed.post()
|
||||||
|
|
||||||
|
|
||||||
# We need this because we rely on the before_prompt hook to notify us
|
# We need this because we rely on the before_prompt hook to notify us
|
||||||
# of frame changes. A dedicated frame change hook would be better.
|
# of frame changes. A dedicated frame change hook would be better.
|
||||||
class FrameCommandInvoker(gui.invoker.Invoker):
|
class FrameCommandInvoker(gui.invoker.Invoker):
|
||||||
@@ -41,8 +43,9 @@ class FrameCommandInvoker(gui.invoker.Invoker):
|
|||||||
gui.invoker.Invoker.do_call(self)
|
gui.invoker.Invoker.do_call(self)
|
||||||
check_frame()
|
check_frame()
|
||||||
|
|
||||||
|
|
||||||
# See my gdb branch on github.
|
# See my gdb branch on github.
|
||||||
if hasattr(gdb.events, 'before_prompt'):
|
if hasattr(gdb.events, "before_prompt"):
|
||||||
gdb.events.before_prompt.connect(check_frame)
|
gdb.events.before_prompt.connect(check_frame)
|
||||||
else:
|
else:
|
||||||
gui.adapt.notify_bug(13598)
|
gui.adapt.notify_bug(13598)
|
||||||
|
@@ -24,16 +24,18 @@ gui_prompt_substitutions = dict(gdb.prompt.prompt_substitutions)
|
|||||||
|
|
||||||
_current_window_for_prompt = None
|
_current_window_for_prompt = None
|
||||||
|
|
||||||
|
|
||||||
def _prompt_window(attr):
|
def _prompt_window(attr):
|
||||||
if _current_window_for_prompt is None:
|
if _current_window_for_prompt is None:
|
||||||
return ''
|
return ""
|
||||||
if attr is None:
|
if attr is None:
|
||||||
return ''
|
return ""
|
||||||
if not hasattr(_current_window_for_prompt, attr):
|
if not hasattr(_current_window_for_prompt, attr):
|
||||||
return None
|
return None
|
||||||
return str(getattr(_current_window_for_prompt, attr))
|
return str(getattr(_current_window_for_prompt, attr))
|
||||||
|
|
||||||
gui_prompt_substitutions['W'] = _prompt_window
|
|
||||||
|
gui_prompt_substitutions["W"] = _prompt_window
|
||||||
|
|
||||||
# GDB's API should do this...
|
# GDB's API should do this...
|
||||||
def substitute_prompt_with_window(prompt, window):
|
def substitute_prompt_with_window(prompt, window):
|
||||||
@@ -49,6 +51,7 @@ def substitute_prompt_with_window(prompt, window):
|
|||||||
_current_window_for_prompt = None
|
_current_window_for_prompt = None
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
# GDB's API should do this...
|
# GDB's API should do this...
|
||||||
def prompt_help_with_window(window):
|
def prompt_help_with_window(window):
|
||||||
global _current_window_for_prompt
|
global _current_window_for_prompt
|
||||||
@@ -63,6 +66,7 @@ def prompt_help_with_window(window):
|
|||||||
_current_window_for_prompt = None
|
_current_window_for_prompt = None
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def is_running():
|
def is_running():
|
||||||
"""Return True if the inferior is running."""
|
"""Return True if the inferior is running."""
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
import gdb
|
import gdb
|
||||||
from gui.startup import in_gdb_thread
|
from gui.startup import in_gdb_thread
|
||||||
|
|
||||||
|
|
||||||
class Invoker(object):
|
class Invoker(object):
|
||||||
"""A simple class that can invoke a gdb command.
|
"""A simple class that can invoke a gdb command.
|
||||||
This is suitable for use as an event handler in Gtk."""
|
This is suitable for use as an event handler in Gtk."""
|
||||||
@@ -26,7 +27,7 @@ class Invoker(object):
|
|||||||
# This is invoked in the gdb thread to run the command.
|
# This is invoked in the gdb thread to run the command.
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def do_call(self):
|
def do_call(self):
|
||||||
gdb.execute(self.cmd, from_tty = True, to_string = True)
|
gdb.execute(self.cmd, from_tty=True, to_string=True)
|
||||||
|
|
||||||
# The object itself is the Gtk event handler -- though really this
|
# The object itself is the Gtk event handler -- though really this
|
||||||
# can be run in any thread.
|
# can be run in any thread.
|
||||||
|
@@ -25,25 +25,26 @@ from gui.startup import in_gtk_thread
|
|||||||
|
|
||||||
default_log_window = None
|
default_log_window = None
|
||||||
|
|
||||||
|
|
||||||
class LogWindow(gui.toplevel.Toplevel):
|
class LogWindow(gui.toplevel.Toplevel):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
global default_log_window
|
global default_log_window
|
||||||
if default_log_window is not None:
|
if default_log_window is not None:
|
||||||
default_log_window.default = ''
|
default_log_window.default = ""
|
||||||
default_log_window = self
|
default_log_window = self
|
||||||
# For the window title.
|
# For the window title.
|
||||||
self.default = ' [Default]'
|
self.default = " [Default]"
|
||||||
super(LogWindow, self).__init__('log')
|
super(LogWindow, self).__init__("log")
|
||||||
|
|
||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def gtk_initialize(self):
|
def gtk_initialize(self):
|
||||||
builder = gui.startup.create_builder('logwindow.xml')
|
builder = gui.startup.create_builder("logwindow.xml")
|
||||||
builder.connect_signals(self)
|
builder.connect_signals(self)
|
||||||
|
|
||||||
self.window = builder.get_object('logwindow')
|
self.window = builder.get_object("logwindow")
|
||||||
self.view = builder.get_object('textview')
|
self.view = builder.get_object("textview")
|
||||||
self.view.modify_font(gui.params.font_manager.get_font())
|
self.view.modify_font(gui.params.font_manager.get_font())
|
||||||
self.buffer = builder.get_object('buffer')
|
self.buffer = builder.get_object("buffer")
|
||||||
|
|
||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def set_font(self, font):
|
def set_font(self, font):
|
||||||
@@ -56,7 +57,7 @@ class LogWindow(gui.toplevel.Toplevel):
|
|||||||
for window in gui.toplevel.state.windows():
|
for window in gui.toplevel.state.windows():
|
||||||
if isinstance(window, LogWindow):
|
if isinstance(window, LogWindow):
|
||||||
default_log_window = window
|
default_log_window = window
|
||||||
window.default = ' [Default]'
|
window.default = " [Default]"
|
||||||
window.update_title()
|
window.update_title()
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@ _initialized = False
|
|||||||
|
|
||||||
_last_time = None
|
_last_time = None
|
||||||
|
|
||||||
|
|
||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def _show_notification(title, content):
|
def _show_notification(title, content):
|
||||||
global _initialized
|
global _initialized
|
||||||
@@ -36,41 +37,45 @@ def _show_notification(title, content):
|
|||||||
n = Notify.Notification.new(title, content)
|
n = Notify.Notification.new(title, content)
|
||||||
n.show()
|
n.show()
|
||||||
|
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def _on_stop(event):
|
def _on_stop(event):
|
||||||
global _last_time
|
global _last_time
|
||||||
t = _last_time
|
t = _last_time
|
||||||
_last_time = None
|
_last_time = None
|
||||||
|
|
||||||
if (t is None
|
if (
|
||||||
|
t is None
|
||||||
or not gui.params.stop_notification.value
|
or not gui.params.stop_notification.value
|
||||||
or time.process_time() - t < gui.params.stop_notification_seconds.value):
|
or time.process_time() - t < gui.params.stop_notification_seconds.value
|
||||||
|
):
|
||||||
return
|
return
|
||||||
|
|
||||||
if isinstance(event, gdb.ExitedEvent):
|
if isinstance(event, gdb.ExitedEvent):
|
||||||
title = 'gdb - inferior exited'
|
title = "gdb - inferior exited"
|
||||||
if hasattr(event, 'exit_code'):
|
if hasattr(event, "exit_code"):
|
||||||
content = 'inferior exited with code ' + str(event.exit_code)
|
content = "inferior exited with code " + str(event.exit_code)
|
||||||
else:
|
else:
|
||||||
content = 'inferior exited, code unavailable'
|
content = "inferior exited, code unavailable"
|
||||||
elif isinstance(event, gdb.BreakpointEvent):
|
elif isinstance(event, gdb.BreakpointEvent):
|
||||||
title = 'gdb - inferior stopped'
|
title = "gdb - inferior stopped"
|
||||||
content = ('inferior stopped at breakpoint '
|
content = "inferior stopped at breakpoint " + str(event.breakpoints[0].number)
|
||||||
+ str(event.breakpoints[0].number))
|
|
||||||
elif isinstance(event, gdb.SignalEvent):
|
elif isinstance(event, gdb.SignalEvent):
|
||||||
title = 'gdb - inferior stopped'
|
title = "gdb - inferior stopped"
|
||||||
content = 'inferior stopped with signal: ' + event.stop_signal
|
content = "inferior stopped with signal: " + event.stop_signal
|
||||||
else:
|
else:
|
||||||
title = 'gdb - inferior stopped'
|
title = "gdb - inferior stopped"
|
||||||
content = 'inferior stopped, reason unknown'
|
content = "inferior stopped, reason unknown"
|
||||||
|
|
||||||
gui.startup.send_to_gtk(lambda: _show_notification(title, content))
|
gui.startup.send_to_gtk(lambda: _show_notification(title, content))
|
||||||
|
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def _on_cont(event):
|
def _on_cont(event):
|
||||||
global _last_time
|
global _last_time
|
||||||
_last_time = time.process_time()
|
_last_time = time.process_time()
|
||||||
|
|
||||||
|
|
||||||
gdb.events.stop.connect(_on_stop)
|
gdb.events.stop.connect(_on_stop)
|
||||||
gdb.events.cont.connect(_on_cont)
|
gdb.events.cont.connect(_on_cont)
|
||||||
gdb.events.exited.connect(_on_stop)
|
gdb.events.exited.connect(_on_stop)
|
||||||
|
138
gui/params.py
138
gui/params.py
@@ -24,33 +24,38 @@ import gui.toplevel
|
|||||||
from gui.startup import in_gdb_thread, in_gtk_thread
|
from gui.startup import in_gdb_thread, in_gtk_thread
|
||||||
from gi.repository import GtkSource, Pango
|
from gi.repository import GtkSource, Pango
|
||||||
|
|
||||||
|
|
||||||
class _SetBase(gdb.Command):
|
class _SetBase(gdb.Command):
|
||||||
"""Generic command for modifying GUI settings."""
|
"""Generic command for modifying GUI settings."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_SetBase, self).__init__('set gui', gdb.COMMAND_NONE,
|
super(_SetBase, self).__init__("set gui", gdb.COMMAND_NONE, prefix=True)
|
||||||
prefix = True)
|
|
||||||
|
|
||||||
class _SetTitleBase(gdb.Command):
|
class _SetTitleBase(gdb.Command):
|
||||||
"""Generic command for modifying GUI window titles."""
|
"""Generic command for modifying GUI window titles."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_SetTitleBase, self).__init__('set gui title', gdb.COMMAND_NONE,
|
super(_SetTitleBase, self).__init__(
|
||||||
prefix = True)
|
"set gui title", gdb.COMMAND_NONE, prefix=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class _ShowBase(gdb.Command):
|
class _ShowBase(gdb.Command):
|
||||||
"""Generic command for showing GUI settings."""
|
"""Generic command for showing GUI settings."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_ShowBase, self).__init__('show gui', gdb.COMMAND_NONE,
|
super(_ShowBase, self).__init__("show gui", gdb.COMMAND_NONE, prefix=True)
|
||||||
prefix = True)
|
|
||||||
|
|
||||||
class _ShowTitleBase(gdb.Command):
|
class _ShowTitleBase(gdb.Command):
|
||||||
"""Generic command for showing GUI window titles."""
|
"""Generic command for showing GUI window titles."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_ShowTitleBase, self).__init__('show gui title', gdb.COMMAND_NONE,
|
super(_ShowTitleBase, self).__init__(
|
||||||
prefix = True)
|
"show gui title", gdb.COMMAND_NONE, prefix=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Like gdb.Parameter, but has a default and automatically handles
|
# Like gdb.Parameter, but has a default and automatically handles
|
||||||
# storage.
|
# storage.
|
||||||
@@ -58,11 +63,10 @@ class _StoredParameter(gdb.Parameter):
|
|||||||
# NAME_FORMAT is like "%s" - NAME is substituted.
|
# NAME_FORMAT is like "%s" - NAME is substituted.
|
||||||
# To construct the parameter name, "gui " is prefixed.
|
# To construct the parameter name, "gui " is prefixed.
|
||||||
def __init__(self, name_format, name, default, c_class, p_kind, *args):
|
def __init__(self, name_format, name, default, c_class, p_kind, *args):
|
||||||
full_name = 'gui ' + name_format % name
|
full_name = "gui " + name_format % name
|
||||||
self.storage_name = '-'.join((name_format % name).split(' '))
|
self.storage_name = "-".join((name_format % name).split(" "))
|
||||||
storage = gui.storage.storage_manager
|
storage = gui.storage.storage_manager
|
||||||
super(_StoredParameter, self).__init__(full_name, c_class, p_kind,
|
super(_StoredParameter, self).__init__(full_name, c_class, p_kind, *args)
|
||||||
*args)
|
|
||||||
if p_kind is gdb.PARAM_BOOLEAN:
|
if p_kind is gdb.PARAM_BOOLEAN:
|
||||||
val = storage.getboolean(self.storage_name)
|
val = storage.getboolean(self.storage_name)
|
||||||
elif p_kind is gdb.PARAM_STRING or p_kind is gdb.PARAM_ENUM:
|
elif p_kind is gdb.PARAM_STRING or p_kind is gdb.PARAM_ENUM:
|
||||||
@@ -87,19 +91,25 @@ class _StoredParameter(gdb.Parameter):
|
|||||||
self.storage.set(self.storage_name, self.value)
|
self.storage.set(self.storage_name, self.value)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
class _Theme(_StoredParameter):
|
class _Theme(_StoredParameter):
|
||||||
# Silly gdb requirement.
|
# Silly gdb requirement.
|
||||||
""
|
""""""
|
||||||
|
|
||||||
set_doc = "Set the source window theme."
|
set_doc = "Set the source window theme."
|
||||||
show_doc = "Show the source window theme."
|
show_doc = "Show the source window theme."
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.manager = GtkSource.StyleSchemeManager.get_default()
|
self.manager = GtkSource.StyleSchemeManager.get_default()
|
||||||
super(_Theme, self).__init__('%s', 'theme', None,
|
super(_Theme, self).__init__(
|
||||||
gdb.COMMAND_NONE, gdb.PARAM_ENUM,
|
"%s",
|
||||||
# Probably the wrong thread.
|
"theme",
|
||||||
self.manager.get_scheme_ids())
|
None,
|
||||||
|
gdb.COMMAND_NONE,
|
||||||
|
gdb.PARAM_ENUM,
|
||||||
|
# Probably the wrong thread.
|
||||||
|
self.manager.get_scheme_ids(),
|
||||||
|
)
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def set_buffer_manager(self, b):
|
def set_buffer_manager(self, b):
|
||||||
@@ -120,17 +130,19 @@ class _Theme(_StoredParameter):
|
|||||||
self.buffer_manager.change_theme()
|
self.buffer_manager.change_theme()
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
class _Font(_StoredParameter):
|
class _Font(_StoredParameter):
|
||||||
# Silly gdb requirement.
|
# Silly gdb requirement.
|
||||||
""
|
""""""
|
||||||
|
|
||||||
set_doc = "Set the source window font."
|
set_doc = "Set the source window font."
|
||||||
show_doc = "Show the source window font."
|
show_doc = "Show the source window font."
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.manager = GtkSource.StyleSchemeManager.get_default()
|
self.manager = GtkSource.StyleSchemeManager.get_default()
|
||||||
super(_Font, self).__init__('%s', 'font', 'monospace',
|
super(_Font, self).__init__(
|
||||||
gdb.COMMAND_NONE, gdb.PARAM_STRING)
|
"%s", "font", "monospace", gdb.COMMAND_NONE, gdb.PARAM_STRING
|
||||||
|
)
|
||||||
|
|
||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def get_font(self):
|
def get_font(self):
|
||||||
@@ -147,11 +159,13 @@ class _Font(_StoredParameter):
|
|||||||
super(_Font, self).get_set_string()
|
super(_Font, self).get_set_string()
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
title_params = {}
|
title_params = {}
|
||||||
|
|
||||||
|
|
||||||
class _Title(_StoredParameter):
|
class _Title(_StoredParameter):
|
||||||
# Silly gdb requirement.
|
# Silly gdb requirement.
|
||||||
""
|
""""""
|
||||||
|
|
||||||
def __init__(self, name, default):
|
def __init__(self, name, default):
|
||||||
title_params[name] = self
|
title_params[name] = self
|
||||||
@@ -159,9 +173,10 @@ class _Title(_StoredParameter):
|
|||||||
self.set_doc = "Set the %s window title format." % self.name
|
self.set_doc = "Set the %s window title format." % self.name
|
||||||
self.show_doc = "Show the %s window title format." % self.name
|
self.show_doc = "Show the %s window title format." % self.name
|
||||||
self.manager = GtkSource.StyleSchemeManager.get_default()
|
self.manager = GtkSource.StyleSchemeManager.get_default()
|
||||||
super(_Title, self).__init__('title %s', name, default,
|
super(_Title, self).__init__(
|
||||||
gdb.COMMAND_NONE, gdb.PARAM_STRING)
|
"title %s", name, default, gdb.COMMAND_NONE, gdb.PARAM_STRING
|
||||||
val = self.storage.get('title-%s' % name)
|
)
|
||||||
|
val = self.storage.get("title-%s" % name)
|
||||||
if val is not None:
|
if val is not None:
|
||||||
self.value = val
|
self.value = val
|
||||||
else:
|
else:
|
||||||
@@ -169,8 +184,7 @@ class _Title(_StoredParameter):
|
|||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_show_string(self, pvalue):
|
def get_show_string(self, pvalue):
|
||||||
return "The current title format for the %s is: %s" % (self.name,
|
return "The current title format for the %s is: %s" % (self.name, self.value)
|
||||||
self.value)
|
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_set_string(self):
|
def get_set_string(self):
|
||||||
@@ -178,16 +192,18 @@ class _Title(_StoredParameter):
|
|||||||
gui.toplevel.state.update_titles()
|
gui.toplevel.state.update_titles()
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
class _Missing(_StoredParameter):
|
class _Missing(_StoredParameter):
|
||||||
# Silly gdb requirement.
|
# Silly gdb requirement.
|
||||||
""
|
""""""
|
||||||
|
|
||||||
set_doc = "Set whether to mention missing gdb features."
|
set_doc = "Set whether to mention missing gdb features."
|
||||||
show_doc = "Show whether to mention missing gdb features."
|
show_doc = "Show whether to mention missing gdb features."
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_Missing, self).__init__('%s', 'mention-missing', True,
|
super(_Missing, self).__init__(
|
||||||
gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)
|
"%s", "mention-missing", True, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN
|
||||||
|
)
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_show_string(self, pvalue):
|
def get_show_string(self, pvalue):
|
||||||
@@ -197,21 +213,22 @@ class _Missing(_StoredParameter):
|
|||||||
v = "off"
|
v = "off"
|
||||||
return "Whether to warn about missing gdb features: " + v
|
return "Whether to warn about missing gdb features: " + v
|
||||||
|
|
||||||
|
|
||||||
class _Lines(_StoredParameter):
|
class _Lines(_StoredParameter):
|
||||||
# Silly gdb requirement.
|
# Silly gdb requirement.
|
||||||
""
|
""""""
|
||||||
|
|
||||||
set_doc = "Set whether to display line numbers in the source window."
|
set_doc = "Set whether to display line numbers in the source window."
|
||||||
show_doc = "Show whether to display line numbers in the source window."
|
show_doc = "Show whether to display line numbers in the source window."
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_Lines, self).__init__('%s', 'line-numbers', False,
|
super(_Lines, self).__init__(
|
||||||
gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)
|
"%s", "line-numbers", False, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN
|
||||||
|
)
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_show_string(self, pvalue):
|
def get_show_string(self, pvalue):
|
||||||
return "The current title format for the %s is: %s" % (self.name,
|
return "The current title format for the %s is: %s" % (self.name, self.value)
|
||||||
self.value)
|
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_set_string(self):
|
def get_set_string(self):
|
||||||
@@ -219,20 +236,24 @@ class _Lines(_StoredParameter):
|
|||||||
gui.toplevel.state.set_line_numbers(self.value)
|
gui.toplevel.state.set_line_numbers(self.value)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
class _Lines(_StoredParameter):
|
class _Lines(_StoredParameter):
|
||||||
# Silly gdb requirement.
|
# Silly gdb requirement.
|
||||||
""
|
""""""
|
||||||
|
|
||||||
set_doc = "Set whether to display line numbers in the source window."
|
set_doc = "Set whether to display line numbers in the source window."
|
||||||
show_doc = "Show whether to display line numbers in the source window."
|
show_doc = "Show whether to display line numbers in the source window."
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_Lines, self).__init__('%s', 'line-numbers', False,
|
super(_Lines, self).__init__(
|
||||||
gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)
|
"%s", "line-numbers", False, gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN
|
||||||
|
)
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_show_string(self, pvalue):
|
def get_show_string(self, pvalue):
|
||||||
return "Whether to display line numbers in the source window is: %s" % self.value
|
return (
|
||||||
|
"Whether to display line numbers in the source window is: %s" % self.value
|
||||||
|
)
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_set_string(self):
|
def get_set_string(self):
|
||||||
@@ -240,16 +261,18 @@ class _Lines(_StoredParameter):
|
|||||||
gui.toplevel.state.set_line_numbers(self.value)
|
gui.toplevel.state.set_line_numbers(self.value)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
class _Tabs(_StoredParameter):
|
class _Tabs(_StoredParameter):
|
||||||
# Silly gdb requirement.
|
# Silly gdb requirement.
|
||||||
""
|
""""""
|
||||||
|
|
||||||
set_doc = "Set width of tabs in the source window."
|
set_doc = "Set width of tabs in the source window."
|
||||||
show_doc = "Show width of tabs in the source window."
|
show_doc = "Show width of tabs in the source window."
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_Tabs, self).__init__('%s', 'tab-width', 8,
|
super(_Tabs, self).__init__(
|
||||||
gdb.COMMAND_NONE, gdb.PARAM_ZINTEGER)
|
"%s", "tab-width", 8, gdb.COMMAND_NONE, gdb.PARAM_ZINTEGER
|
||||||
|
)
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_show_string(self, pvalue):
|
def get_show_string(self, pvalue):
|
||||||
@@ -261,40 +284,45 @@ class _Tabs(_StoredParameter):
|
|||||||
gui.toplevel.state.set_tab_width(self.value)
|
gui.toplevel.state.set_tab_width(self.value)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
class _StopNotification(_StoredParameter):
|
class _StopNotification(_StoredParameter):
|
||||||
# Silly gdb requirement.
|
# Silly gdb requirement.
|
||||||
""
|
""""""
|
||||||
|
|
||||||
set_doc = "Set whether stop notifications are displayed."
|
set_doc = "Set whether stop notifications are displayed."
|
||||||
show_doc = "Show whether stop notifications are displayed."
|
show_doc = "Show whether stop notifications are displayed."
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_StopNotification, self).__init__('%s', 'stop-notification', True,
|
super(_StopNotification, self).__init__(
|
||||||
gdb.COMMAND_RUNNING,
|
"%s", "stop-notification", True, gdb.COMMAND_RUNNING, gdb.PARAM_BOOLEAN
|
||||||
gdb.PARAM_BOOLEAN)
|
)
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_show_string(self, pvalue):
|
def get_show_string(self, pvalue):
|
||||||
return "Whether stop notifications are displayed is: %s" % self.value
|
return "Whether stop notifications are displayed is: %s" % self.value
|
||||||
|
|
||||||
|
|
||||||
class _StopNotificationSeconds(_StoredParameter):
|
class _StopNotificationSeconds(_StoredParameter):
|
||||||
# Silly gdb requirement.
|
# Silly gdb requirement.
|
||||||
""
|
""""""
|
||||||
|
|
||||||
set_doc = "Set stop notification timeout in seconds."
|
set_doc = "Set stop notification timeout in seconds."
|
||||||
show_doc = "Show stop notification timeout."
|
show_doc = "Show stop notification timeout."
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(_StopNotificationSeconds, self).__init__('%s',
|
super(_StopNotificationSeconds, self).__init__(
|
||||||
'stop-notification-seconds',
|
"%s",
|
||||||
120,
|
"stop-notification-seconds",
|
||||||
gdb.COMMAND_RUNNING,
|
120,
|
||||||
gdb.PARAM_ZINTEGER)
|
gdb.COMMAND_RUNNING,
|
||||||
|
gdb.PARAM_ZINTEGER,
|
||||||
|
)
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def get_show_string(self, pvalue):
|
def get_show_string(self, pvalue):
|
||||||
return "Stop notifications are displayed after %d seconds." % self.value
|
return "Stop notifications are displayed after %d seconds." % self.value
|
||||||
|
|
||||||
|
|
||||||
_SetBase()
|
_SetBase()
|
||||||
_SetTitleBase()
|
_SetTitleBase()
|
||||||
_ShowBase()
|
_ShowBase()
|
||||||
@@ -304,10 +332,10 @@ font_manager = _Font()
|
|||||||
stop_notification = _StopNotification()
|
stop_notification = _StopNotification()
|
||||||
stop_notification_seconds = _StopNotificationSeconds()
|
stop_notification_seconds = _StopNotificationSeconds()
|
||||||
|
|
||||||
_Title('source', '\\W{basename} [GDB Source @\\W{number}]')
|
_Title("source", "\\W{basename} [GDB Source @\\W{number}]")
|
||||||
_Title('display', '\\W{command} [GDB Display @\\W{number}]')
|
_Title("display", "\\W{command} [GDB Display @\\W{number}]")
|
||||||
_Title('log', '[GDB Log @\\W{number}]\\W{default}')
|
_Title("log", "[GDB Log @\\W{number}]\\W{default}")
|
||||||
_Title('stack', '[GDB Stack @\\W{number}]')
|
_Title("stack", "[GDB Stack @\\W{number}]")
|
||||||
|
|
||||||
warn_missing = _Missing()
|
warn_missing = _Missing()
|
||||||
line_numbers = _Lines()
|
line_numbers = _Lines()
|
||||||
|
@@ -31,6 +31,7 @@ import gui.bpcache
|
|||||||
|
|
||||||
from gi.repository import Gtk, GtkSource, GObject, Gdk, GdkPixbuf, Pango
|
from gi.repository import Gtk, GtkSource, GObject, Gdk, GdkPixbuf, Pango
|
||||||
|
|
||||||
|
|
||||||
class BufferManager:
|
class BufferManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.buffers = {}
|
self.buffers = {}
|
||||||
@@ -38,7 +39,7 @@ class BufferManager:
|
|||||||
gui.params.source_theme.set_buffer_manager(self)
|
gui.params.source_theme.set_buffer_manager(self)
|
||||||
gui.events.location_changed.connect(self._location_changed)
|
gui.events.location_changed.connect(self._location_changed)
|
||||||
# FIXME - emit a warning if this isn't available.
|
# FIXME - emit a warning if this isn't available.
|
||||||
if hasattr(gdb.events, 'clear_objfiles'):
|
if hasattr(gdb.events, "clear_objfiles"):
|
||||||
gdb.events.clear_objfiles.connect(self._clear_objfiles)
|
gdb.events.clear_objfiles.connect(self._clear_objfiles)
|
||||||
self.empty_buffer = None
|
self.empty_buffer = None
|
||||||
|
|
||||||
@@ -60,13 +61,13 @@ class BufferManager:
|
|||||||
while True:
|
while True:
|
||||||
line = iter.get_line() + 1
|
line = iter.get_line() + 1
|
||||||
if line in line_set:
|
if line in line_set:
|
||||||
buffer.create_source_mark(None, 'executable', iter)
|
buffer.create_source_mark(None, "executable", iter)
|
||||||
if not iter.forward_line():
|
if not iter.forward_line():
|
||||||
break
|
break
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def _get_lines_update(self, buffer, symtab):
|
def _get_lines_update(self, buffer, symtab):
|
||||||
if hasattr(symtab, 'linetable'):
|
if hasattr(symtab, "linetable"):
|
||||||
line_set = set(symtab.linetable().source_lines())
|
line_set = set(symtab.linetable().source_lines())
|
||||||
gui.startup.send_to_gtk(lambda: self._set_marks(buffer, line_set))
|
gui.startup.send_to_gtk(lambda: self._set_marks(buffer, line_set))
|
||||||
|
|
||||||
@@ -113,9 +114,9 @@ class BufferManager:
|
|||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def update_breakpoint_location(self, sal, is_set):
|
def update_breakpoint_location(self, sal, is_set):
|
||||||
if is_set:
|
if is_set:
|
||||||
category = 'breakpoint'
|
category = "breakpoint"
|
||||||
else:
|
else:
|
||||||
category = 'executable'
|
category = "executable"
|
||||||
[fullname, line] = sal
|
[fullname, line] = sal
|
||||||
if fullname in self.buffers:
|
if fullname in self.buffers:
|
||||||
buffer = self.buffers[fullname]
|
buffer = self.buffers[fullname]
|
||||||
@@ -125,8 +126,7 @@ class BufferManager:
|
|||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def _location_changed(self, loc, is_set):
|
def _location_changed(self, loc, is_set):
|
||||||
gui.startup.send_to_gtk(lambda: self.update_breakpoint_location(loc,
|
gui.startup.send_to_gtk(lambda: self.update_breakpoint_location(loc, is_set))
|
||||||
is_set))
|
|
||||||
|
|
||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def _gtk_clear_objfiles(self):
|
def _gtk_clear_objfiles(self):
|
||||||
@@ -144,9 +144,10 @@ class BufferManager:
|
|||||||
for key in self.buffers:
|
for key in self.buffers:
|
||||||
buff = self.buffers[key]
|
buff = self.buffers[key]
|
||||||
# This could probably be more efficient.
|
# This could probably be more efficient.
|
||||||
buff.remove_source_marks(buff.get_start_iter(),
|
buff.remove_source_marks(
|
||||||
buff.get_end_iter(),
|
buff.get_start_iter(), buff.get_end_iter(), "pointer"
|
||||||
'pointer')
|
)
|
||||||
|
|
||||||
|
|
||||||
buffer_manager = BufferManager()
|
buffer_manager = BufferManager()
|
||||||
|
|
||||||
@@ -168,7 +169,7 @@ def get_current_location():
|
|||||||
# No frame - try 'main'.
|
# No frame - try 'main'.
|
||||||
try:
|
try:
|
||||||
frame = None
|
frame = None
|
||||||
sym = gdb.lookup_global_symbol('main')
|
sym = gdb.lookup_global_symbol("main")
|
||||||
lineno = sym.line
|
lineno = sym.line
|
||||||
symtab = sym.symtab
|
symtab = sym.symtab
|
||||||
filename = symtab.fullname()
|
filename = symtab.fullname()
|
||||||
@@ -179,6 +180,7 @@ def get_current_location():
|
|||||||
return (None, None, None, None)
|
return (None, None, None, None)
|
||||||
return (frame, symtab, filename, lineno)
|
return (frame, symtab, filename, lineno)
|
||||||
|
|
||||||
|
|
||||||
class LRUHandler:
|
class LRUHandler:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.windows = []
|
self.windows = []
|
||||||
@@ -190,10 +192,9 @@ class LRUHandler:
|
|||||||
if len(self.windows) == 0:
|
if len(self.windows) == 0:
|
||||||
self.work_location = (frame, symtab, srcfile, srcline)
|
self.work_location = (frame, symtab, srcfile, srcline)
|
||||||
SourceWindow()
|
SourceWindow()
|
||||||
gui.startup.send_to_gtk(lambda: self.show_source(frame,
|
gui.startup.send_to_gtk(
|
||||||
symtab,
|
lambda: self.show_source(frame, symtab, srcfile, srcline)
|
||||||
srcfile,
|
)
|
||||||
srcline))
|
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def new_source_window(self):
|
def new_source_window(self):
|
||||||
@@ -204,16 +205,15 @@ class LRUHandler:
|
|||||||
def on_event(self, *args):
|
def on_event(self, *args):
|
||||||
(frame, symtab, filename, lineno) = get_current_location()
|
(frame, symtab, filename, lineno) = get_current_location()
|
||||||
if filename is not None:
|
if filename is not None:
|
||||||
gui.startup.send_to_gtk(lambda: self.show_source(frame,
|
gui.startup.send_to_gtk(
|
||||||
symtab,
|
lambda: self.show_source(frame, symtab, filename, lineno)
|
||||||
filename,
|
)
|
||||||
lineno))
|
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def _connect_events(self):
|
def _connect_events(self):
|
||||||
gdb.events.stop.connect(self.on_event)
|
gdb.events.stop.connect(self.on_event)
|
||||||
gui.events.frame_changed.connect(self.on_event)
|
gui.events.frame_changed.connect(self.on_event)
|
||||||
if hasattr(gdb.events, 'new_objfile'):
|
if hasattr(gdb.events, "new_objfile"):
|
||||||
gdb.events.new_objfile.connect(self._new_objfile)
|
gdb.events.new_objfile.connect(self._new_objfile)
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
@@ -263,27 +263,28 @@ class LRUHandler:
|
|||||||
if self.work_location is not None:
|
if self.work_location is not None:
|
||||||
(frame, symtab, filename, lineno) = self.work_location
|
(frame, symtab, filename, lineno) = self.work_location
|
||||||
self.work_location = None
|
self.work_location = None
|
||||||
gui.startup.send_to_gtk(lambda: self.show_source(frame,
|
gui.startup.send_to_gtk(
|
||||||
symtab,
|
lambda: self.show_source(frame, symtab, filename, lineno)
|
||||||
filename,
|
)
|
||||||
lineno))
|
|
||||||
|
|
||||||
@in_gdb_thread
|
@in_gdb_thread
|
||||||
def _new_objfile(self, event):
|
def _new_objfile(self, event):
|
||||||
if len(gdb.objfiles()) == 1:
|
if len(gdb.objfiles()) == 1:
|
||||||
self.on_event()
|
self.on_event()
|
||||||
|
|
||||||
|
|
||||||
lru_handler = LRUHandler()
|
lru_handler = LRUHandler()
|
||||||
|
|
||||||
BUTTON_NAMES = ["step", "next", "continue", "finish", "stop", "up", "down"]
|
BUTTON_NAMES = ["step", "next", "continue", "finish", "stop", "up", "down"]
|
||||||
|
|
||||||
|
|
||||||
class SourceWindow(gui.updatewindow.UpdateWindow):
|
class SourceWindow(gui.updatewindow.UpdateWindow):
|
||||||
def _get_pixmap(self, filename):
|
def _get_pixmap(self, filename):
|
||||||
path = os.path.join(gui.self_dir, filename)
|
path = os.path.join(gui.self_dir, filename)
|
||||||
return GdkPixbuf.Pixbuf.new_from_file(path)
|
return GdkPixbuf.Pixbuf.new_from_file(path)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(SourceWindow, self).__init__('source')
|
super(SourceWindow, self).__init__("source")
|
||||||
gdb.events.cont.connect(self._on_cont_event)
|
gdb.events.cont.connect(self._on_cont_event)
|
||||||
# Update the buttons.
|
# Update the buttons.
|
||||||
self.on_event()
|
self.on_event()
|
||||||
@@ -300,7 +301,7 @@ class SourceWindow(gui.updatewindow.UpdateWindow):
|
|||||||
self.do_up = FrameCommandInvoker("up")
|
self.do_up = FrameCommandInvoker("up")
|
||||||
self.do_down = FrameCommandInvoker("down")
|
self.do_down = FrameCommandInvoker("down")
|
||||||
|
|
||||||
builder = gui.startup.create_builder('sourcewindow.xml')
|
builder = gui.startup.create_builder("sourcewindow.xml")
|
||||||
builder.connect_signals(self)
|
builder.connect_signals(self)
|
||||||
self.window = builder.get_object("sourcewindow")
|
self.window = builder.get_object("sourcewindow")
|
||||||
self.view = builder.get_object("view")
|
self.view = builder.get_object("view")
|
||||||
@@ -315,16 +316,16 @@ class SourceWindow(gui.updatewindow.UpdateWindow):
|
|||||||
self.view.set_tab_width(gui.params.tab_width.value)
|
self.view.set_tab_width(gui.params.tab_width.value)
|
||||||
|
|
||||||
attrs = GtkSource.MarkAttributes()
|
attrs = GtkSource.MarkAttributes()
|
||||||
attrs.set_pixbuf(self._get_pixmap('icons/ok.png'))
|
attrs.set_pixbuf(self._get_pixmap("icons/ok.png"))
|
||||||
self.view.set_mark_attributes('executable', attrs, 0)
|
self.view.set_mark_attributes("executable", attrs, 0)
|
||||||
|
|
||||||
attrs = GtkSource.MarkAttributes()
|
attrs = GtkSource.MarkAttributes()
|
||||||
attrs.set_pixbuf(self._get_pixmap('icons/breakpoint-marker.png'))
|
attrs.set_pixbuf(self._get_pixmap("icons/breakpoint-marker.png"))
|
||||||
self.view.set_mark_attributes('breakpoint', attrs, 1)
|
self.view.set_mark_attributes("breakpoint", attrs, 1)
|
||||||
|
|
||||||
attrs = GtkSource.MarkAttributes()
|
attrs = GtkSource.MarkAttributes()
|
||||||
attrs.set_pixbuf(self._get_pixmap('icons/line-pointer.png'))
|
attrs.set_pixbuf(self._get_pixmap("icons/line-pointer.png"))
|
||||||
self.view.set_mark_attributes('pointer', attrs, 2)
|
self.view.set_mark_attributes("pointer", attrs, 2)
|
||||||
|
|
||||||
self.view.set_buffer(buffer_manager.get_empty_buffer())
|
self.view.set_buffer(buffer_manager.get_empty_buffer())
|
||||||
lru_handler.add(self)
|
lru_handler.add(self)
|
||||||
@@ -363,14 +364,14 @@ class SourceWindow(gui.updatewindow.UpdateWindow):
|
|||||||
filename = self.view.get_buffer().filename
|
filename = self.view.get_buffer().filename
|
||||||
line = textiter.get_line() + 1
|
line = textiter.get_line() + 1
|
||||||
if gui.bpcache.any_breakpoint_at(filename, line):
|
if gui.bpcache.any_breakpoint_at(filename, line):
|
||||||
fun = Invoker("clear %s:%d" % (filename,line))
|
fun = Invoker("clear %s:%d" % (filename, line))
|
||||||
else:
|
else:
|
||||||
fun = Invoker("break %s:%d" % (filename, line))
|
fun = Invoker("break %s:%d" % (filename, line))
|
||||||
fun()
|
fun()
|
||||||
|
|
||||||
def _do_scroll(self, buff, srcline):
|
def _do_scroll(self, buff, srcline):
|
||||||
iter = buff.get_iter_at_line(srcline)
|
iter = buff.get_iter_at_line(srcline)
|
||||||
buff.create_source_mark(None, 'pointer', iter)
|
buff.create_source_mark(None, "pointer", iter)
|
||||||
buff.place_cursor(iter)
|
buff.place_cursor(iter)
|
||||||
self.view.scroll_mark_onscreen(buff.get_insert())
|
self.view.scroll_mark_onscreen(buff.get_insert())
|
||||||
return False
|
return False
|
||||||
|
27
gui/stack.py
27
gui/stack.py
@@ -27,6 +27,7 @@ from gui.framecache import FrameCommandInvoker
|
|||||||
from gui.startup import in_gdb_thread, in_gtk_thread
|
from gui.startup import in_gdb_thread, in_gtk_thread
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
|
|
||||||
def format_frame(frame):
|
def format_frame(frame):
|
||||||
result = {}
|
result = {}
|
||||||
result["name"] = frame.function()
|
result["name"] = frame.function()
|
||||||
@@ -42,10 +43,11 @@ def format_frame(frame):
|
|||||||
return result
|
return result
|
||||||
# FIXME args
|
# FIXME args
|
||||||
|
|
||||||
|
|
||||||
class StackWindow(gui.updatewindow.UpdateWindow):
|
class StackWindow(gui.updatewindow.UpdateWindow):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.raw = False
|
self.raw = False
|
||||||
super(StackWindow, self).__init__('stack')
|
super(StackWindow, self).__init__("stack")
|
||||||
# Connect events.
|
# Connect events.
|
||||||
# Update buttons.
|
# Update buttons.
|
||||||
|
|
||||||
@@ -53,11 +55,11 @@ class StackWindow(gui.updatewindow.UpdateWindow):
|
|||||||
def gtk_initialize(self):
|
def gtk_initialize(self):
|
||||||
self.do_up = FrameCommandInvoker("up")
|
self.do_up = FrameCommandInvoker("up")
|
||||||
self.do_down = FrameCommandInvoker("down")
|
self.do_down = FrameCommandInvoker("down")
|
||||||
builder = gui.startup.create_builder('stackwindow.xml')
|
builder = gui.startup.create_builder("stackwindow.xml")
|
||||||
builder.connect_signals(self)
|
builder.connect_signals(self)
|
||||||
|
|
||||||
self.window = builder.get_object('stackwindow')
|
self.window = builder.get_object("stackwindow")
|
||||||
self.view = builder.get_object('view')
|
self.view = builder.get_object("view")
|
||||||
self.text = Gtk.TextBuffer()
|
self.text = Gtk.TextBuffer()
|
||||||
self.view.set_buffer(self.text)
|
self.view.set_buffer(self.text)
|
||||||
self.view.modify_font(gui.params.font_manager.get_font())
|
self.view.modify_font(gui.params.font_manager.get_font())
|
||||||
@@ -67,7 +69,7 @@ class StackWindow(gui.updatewindow.UpdateWindow):
|
|||||||
self.text.delete(self.text.get_start_iter(), self.text.get_end_iter())
|
self.text.delete(self.text.get_start_iter(), self.text.get_end_iter())
|
||||||
frame_no = 1
|
frame_no = 1
|
||||||
for frame in data:
|
for frame in data:
|
||||||
self.text.insert_at_cursor('#%d ' % frame_no)
|
self.text.insert_at_cursor("#%d " % frame_no)
|
||||||
frame_no = frame_no + 1
|
frame_no = frame_no + 1
|
||||||
# Goofball API.
|
# Goofball API.
|
||||||
if isinstance(frame["name"], str):
|
if isinstance(frame["name"], str):
|
||||||
@@ -80,8 +82,9 @@ class StackWindow(gui.updatewindow.UpdateWindow):
|
|||||||
# FIXME args
|
# FIXME args
|
||||||
self.text.insert_at_cursor("\n")
|
self.text.insert_at_cursor("\n")
|
||||||
if frame["line"] is not None:
|
if frame["line"] is not None:
|
||||||
self.text.insert_at_cursor(" at %s:%d\n" % (frame["filename"],
|
self.text.insert_at_cursor(
|
||||||
frame["line"]))
|
" at %s:%d\n" % (frame["filename"], frame["line"])
|
||||||
|
)
|
||||||
if frame["solib"] is not None:
|
if frame["solib"] is not None:
|
||||||
self.text.insert_at_cursor(" [%s]\n" % frame["solib"])
|
self.text.insert_at_cursor(" [%s]\n" % frame["solib"])
|
||||||
|
|
||||||
@@ -91,11 +94,12 @@ class StackWindow(gui.updatewindow.UpdateWindow):
|
|||||||
try:
|
try:
|
||||||
start_frame = gdb.newest_frame()
|
start_frame = gdb.newest_frame()
|
||||||
if not self.raw:
|
if not self.raw:
|
||||||
frame_iter = gdb.frames.execute_frame_filters(start_frame,
|
frame_iter = gdb.frames.execute_frame_filters(start_frame, 0, -1)
|
||||||
0, -1)
|
|
||||||
if frame_iter is None:
|
if frame_iter is None:
|
||||||
frame_iter = map(gdb.FrameDecorator.FrameDecorator,
|
frame_iter = map(
|
||||||
gdb.FrameIterator.FrameIterator(start_frame))
|
gdb.FrameDecorator.FrameDecorator,
|
||||||
|
gdb.FrameIterator.FrameIterator(start_frame),
|
||||||
|
)
|
||||||
data = list(map(format_frame, frame_iter))
|
data = list(map(format_frame, frame_iter))
|
||||||
except gdb.error:
|
except gdb.error:
|
||||||
data = []
|
data = []
|
||||||
@@ -105,6 +109,7 @@ class StackWindow(gui.updatewindow.UpdateWindow):
|
|||||||
def set_font(self, pango_font):
|
def set_font(self, pango_font):
|
||||||
self.view.modify_font(pango_font)
|
self.view.modify_font(pango_font)
|
||||||
|
|
||||||
|
|
||||||
def show_stack():
|
def show_stack():
|
||||||
# for now
|
# for now
|
||||||
StackWindow()
|
StackWindow()
|
||||||
|
@@ -22,9 +22,9 @@ import gui
|
|||||||
|
|
||||||
import gi
|
import gi
|
||||||
|
|
||||||
gi.require_version('Gtk', '3.0')
|
gi.require_version("Gtk", "3.0")
|
||||||
gi.require_version('GtkSource', '3.0')
|
gi.require_version("GtkSource", "3.0")
|
||||||
gi.require_version('Notify', '0.7')
|
gi.require_version("Notify", "0.7")
|
||||||
|
|
||||||
from gi.repository import Gtk, Gdk, GObject, GtkSource, GLib, GdkPixbuf
|
from gi.repository import Gtk, Gdk, GObject, GtkSource, GLib, GdkPixbuf
|
||||||
|
|
||||||
@@ -32,11 +32,13 @@ from gi.repository import Gtk, Gdk, GObject, GtkSource, GLib, GdkPixbuf
|
|||||||
|
|
||||||
_event_queue = queue.Queue()
|
_event_queue = queue.Queue()
|
||||||
|
|
||||||
|
|
||||||
def send_to_gtk(func):
|
def send_to_gtk(func):
|
||||||
_event_queue.put(func)
|
_event_queue.put(func)
|
||||||
# The payload is arbitrary.
|
# The payload is arbitrary.
|
||||||
os.write(write_pipe, bytes(1))
|
os.write(write_pipe, bytes(1))
|
||||||
|
|
||||||
|
|
||||||
class _GtkThread(gdb.Thread):
|
class _GtkThread(gdb.Thread):
|
||||||
def handle_queue(self, source, condition):
|
def handle_queue(self, source, condition):
|
||||||
global _event_queue
|
global _event_queue
|
||||||
@@ -51,17 +53,19 @@ class _GtkThread(gdb.Thread):
|
|||||||
GObject.type_register(GtkSource.View)
|
GObject.type_register(GtkSource.View)
|
||||||
Gtk.main()
|
Gtk.main()
|
||||||
|
|
||||||
|
|
||||||
_gdb_thread = threading.current_thread()
|
_gdb_thread = threading.current_thread()
|
||||||
_t = None
|
_t = None
|
||||||
|
|
||||||
|
|
||||||
def start_gtk():
|
def start_gtk():
|
||||||
global _t
|
global _t
|
||||||
if _t is None:
|
if _t is None:
|
||||||
GLib.set_application_name('GDB')
|
GLib.set_application_name("GDB")
|
||||||
GLib.set_prgname('GDB')
|
GLib.set_prgname("GDB")
|
||||||
Gdk.set_program_class('GDB')
|
Gdk.set_program_class("GDB")
|
||||||
Gtk.Window.set_default_icon_name('GDB')
|
Gtk.Window.set_default_icon_name("GDB")
|
||||||
path = os.path.join(gui.self_dir, 'icons/face-raspberry-symbolic.svg')
|
path = os.path.join(gui.self_dir, "icons/face-raspberry-symbolic.svg")
|
||||||
Gtk.Window.set_default_icon(GdkPixbuf.Pixbuf.new_from_file(path))
|
Gtk.Window.set_default_icon(GdkPixbuf.Pixbuf.new_from_file(path))
|
||||||
GObject.threads_init()
|
GObject.threads_init()
|
||||||
Gdk.threads_init()
|
Gdk.threads_init()
|
||||||
@@ -69,21 +73,26 @@ def start_gtk():
|
|||||||
_t.setDaemon(True)
|
_t.setDaemon(True)
|
||||||
_t.start()
|
_t.start()
|
||||||
|
|
||||||
|
|
||||||
def create_builder(filename):
|
def create_builder(filename):
|
||||||
builder = Gtk.Builder()
|
builder = Gtk.Builder()
|
||||||
builder.add_from_file(os.path.join(gui.self_dir, filename))
|
builder.add_from_file(os.path.join(gui.self_dir, filename))
|
||||||
return builder
|
return builder
|
||||||
|
|
||||||
|
|
||||||
def in_gdb_thread(func):
|
def in_gdb_thread(func):
|
||||||
def ensure_gdb_thread(*args, **kwargs):
|
def ensure_gdb_thread(*args, **kwargs):
|
||||||
if threading.current_thread() is not _gdb_thread:
|
if threading.current_thread() is not _gdb_thread:
|
||||||
raise RuntimeError("must run '%s' in gdb thread" % repr(func))
|
raise RuntimeError("must run '%s' in gdb thread" % repr(func))
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
return ensure_gdb_thread
|
return ensure_gdb_thread
|
||||||
|
|
||||||
|
|
||||||
def in_gtk_thread(func):
|
def in_gtk_thread(func):
|
||||||
def ensure_gtk_thread(*args, **kwargs):
|
def ensure_gtk_thread(*args, **kwargs):
|
||||||
if threading.current_thread() is not _t:
|
if threading.current_thread() is not _t:
|
||||||
raise RuntimeError("must run '%s' in Gtk thread" % repr(func))
|
raise RuntimeError("must run '%s' in Gtk thread" % repr(func))
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
return ensure_gtk_thread
|
return ensure_gtk_thread
|
||||||
|
@@ -21,10 +21,11 @@ import errno
|
|||||||
import configparser
|
import configparser
|
||||||
import atexit
|
import atexit
|
||||||
|
|
||||||
|
|
||||||
class StorageManager:
|
class StorageManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.dir = os.path.join(GLib.get_user_config_dir(), 'gdb')
|
self.dir = os.path.join(GLib.get_user_config_dir(), "gdb")
|
||||||
self.file = os.path.join(self.dir, 'settings')
|
self.file = os.path.join(self.dir, "settings")
|
||||||
try:
|
try:
|
||||||
os.mkdir(self.dir, 0o700)
|
os.mkdir(self.dir, 0o700)
|
||||||
except OSError as exc:
|
except OSError as exc:
|
||||||
@@ -33,30 +34,31 @@ class StorageManager:
|
|||||||
self.config = configparser.RawConfigParser()
|
self.config = configparser.RawConfigParser()
|
||||||
if self.file is not None:
|
if self.file is not None:
|
||||||
self.config.read(self.file)
|
self.config.read(self.file)
|
||||||
if not self.config.has_section('general'):
|
if not self.config.has_section("general"):
|
||||||
self.config.add_section('general')
|
self.config.add_section("general")
|
||||||
atexit.register(self.write)
|
atexit.register(self.write)
|
||||||
|
|
||||||
def get(self, name):
|
def get(self, name):
|
||||||
if self.config.has_option('general', name):
|
if self.config.has_option("general", name):
|
||||||
return self.config.get('general', name)
|
return self.config.get("general", name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getboolean(self, name):
|
def getboolean(self, name):
|
||||||
if self.config.has_option('general', name):
|
if self.config.has_option("general", name):
|
||||||
return self.config.getboolean('general', name)
|
return self.config.getboolean("general", name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getint(self, name):
|
def getint(self, name):
|
||||||
if self.config.has_option('general', name):
|
if self.config.has_option("general", name):
|
||||||
return self.config.getint('general', name)
|
return self.config.getint("general", name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set(self, name, value):
|
def set(self, name, value):
|
||||||
self.config.set('general', name, value)
|
self.config.set("general", name, value)
|
||||||
|
|
||||||
def write(self):
|
def write(self):
|
||||||
with open(self.file, 'wt') as save_file:
|
with open(self.file, "wt") as save_file:
|
||||||
self.config.write(save_file)
|
self.config.write(save_file)
|
||||||
|
|
||||||
|
|
||||||
storage_manager = StorageManager()
|
storage_manager = StorageManager()
|
||||||
|
@@ -25,6 +25,7 @@ import threading
|
|||||||
from gi.repository import Pango
|
from gi.repository import Pango
|
||||||
from gui.startup import in_gdb_thread, in_gtk_thread
|
from gui.startup import in_gdb_thread, in_gtk_thread
|
||||||
|
|
||||||
|
|
||||||
class _ToplevelState(object):
|
class _ToplevelState(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
gui.startup.start_gtk()
|
gui.startup.start_gtk()
|
||||||
@@ -73,12 +74,11 @@ class _ToplevelState(object):
|
|||||||
print("No windows")
|
print("No windows")
|
||||||
return
|
return
|
||||||
|
|
||||||
print(' Num Name')
|
print(" Num Name")
|
||||||
for winno in range(1, self.next_toplevel):
|
for winno in range(1, self.next_toplevel):
|
||||||
if winno in self.toplevels:
|
if winno in self.toplevels:
|
||||||
window = self.toplevels[winno]
|
window = self.toplevels[winno]
|
||||||
print(' %3d %s' % (window.number,
|
print(" %3d %s" % (window.number, window.window.get_title()))
|
||||||
window.window.get_title()))
|
|
||||||
|
|
||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def _do_set_font(self, font_name):
|
def _do_set_font(self, font_name):
|
||||||
@@ -125,15 +125,17 @@ class _ToplevelState(object):
|
|||||||
def windows(self):
|
def windows(self):
|
||||||
return list(self.toplevels.values())
|
return list(self.toplevels.values())
|
||||||
|
|
||||||
|
|
||||||
state = _ToplevelState()
|
state = _ToplevelState()
|
||||||
|
|
||||||
|
|
||||||
class Toplevel(object):
|
class Toplevel(object):
|
||||||
def __init__(self, window_type):
|
def __init__(self, window_type):
|
||||||
state.add(self, window_type)
|
state.add(self, window_type)
|
||||||
# The subclass must set this.
|
# The subclass must set this.
|
||||||
self.window = None
|
self.window = None
|
||||||
self.window_type = window_type
|
self.window_type = window_type
|
||||||
self.storage_name = window_type + '-' + str(self.type_number) + '-geom'
|
self.storage_name = window_type + "-" + str(self.type_number) + "-geom"
|
||||||
gui.startup.send_to_gtk(self._do_gtk_initialize)
|
gui.startup.send_to_gtk(self._do_gtk_initialize)
|
||||||
|
|
||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
@@ -145,7 +147,7 @@ class Toplevel(object):
|
|||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def _do_gtk_initialize(self):
|
def _do_gtk_initialize(self):
|
||||||
self.gtk_initialize()
|
self.gtk_initialize()
|
||||||
self.window.connect('configure-event', self._on_resize)
|
self.window.connect("configure-event", self._on_resize)
|
||||||
geom = gui.storage.storage_manager.get(self.storage_name)
|
geom = gui.storage.storage_manager.get(self.storage_name)
|
||||||
if geom:
|
if geom:
|
||||||
self.window.parse_geometry(geom)
|
self.window.parse_geometry(geom)
|
||||||
@@ -158,7 +160,7 @@ class Toplevel(object):
|
|||||||
|
|
||||||
@in_gtk_thread
|
@in_gtk_thread
|
||||||
def _on_resize(self, widget, event):
|
def _on_resize(self, widget, event):
|
||||||
geom = '%dx%d+%d+%d' % (event.width, event.height, event.x, event.y)
|
geom = "%dx%d+%d+%d" % (event.width, event.height, event.x, event.y)
|
||||||
gdb.post_event(lambda: self._save_size(geom))
|
gdb.post_event(lambda: self._save_size(geom))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@@ -21,6 +21,7 @@ from gui.startup import in_gdb_thread, in_gtk_thread
|
|||||||
import gdb
|
import gdb
|
||||||
import gui.events
|
import gui.events
|
||||||
|
|
||||||
|
|
||||||
class UpdateWindow(Toplevel):
|
class UpdateWindow(Toplevel):
|
||||||
"""A window that automatically updates in response to gdb changes.
|
"""A window that automatically updates in response to gdb changes.
|
||||||
|
|
||||||
|
5
pyproject.toml
Normal file
5
pyproject.toml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[tool.black]
|
||||||
|
include = "\\.py(\\.in)?$"
|
||||||
|
|
||||||
|
[tool.pyright]
|
||||||
|
typeCheckingMode = "strict"
|
Reference in New Issue
Block a user