Skip to content

Commit 3809cd2

Browse files
committed
contrib: Add command support to ptdrgn.py
Signed-off-by: Stephen Brennan <[email protected]>
1 parent 8b31350 commit 3809cd2

File tree

1 file changed

+43
-1
lines changed

1 file changed

+43
-1
lines changed

contrib/ptdrgn.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,28 @@
1111
1212
Requires: "pip install ptpython" which brings in pygments and prompt_toolkit
1313
"""
14+
import builtins
1415
import functools
1516
import importlib
1617
import os
1718
import shutil
1819
import sys
1920
from typing import Any, Callable, Dict, Optional, Set
2021

22+
import ptpython.repl
2123
from prompt_toolkit.completion import Completion, Completer
24+
from prompt_toolkit.document import Document
2225
from prompt_toolkit.formatted_text import PygmentsTokens
2326
from prompt_toolkit.formatted_text import fragment_list_to_text, to_formatted_text
2427
from ptpython import embed
2528
from ptpython.completer import DictionaryCompleter
26-
from ptpython.repl import run_config
29+
from ptpython.repl import PythonRepl, run_config
30+
from ptpython.validator import PythonValidator
2731
from pygments.lexers.c_cpp import CLexer
2832

2933
import drgn
3034
import drgn.cli
35+
from drgn.cli import all_commands, Command, help_command
3136

3237

3338
class DummyForRepr:
@@ -124,10 +129,40 @@ def _format_result_output(result: object):
124129
repl.completer = ReorderDrgnObjectCompleter(repl.completer)
125130

126131

132+
class DrgnPythonValidator(PythonValidator):
133+
134+
def validate(self, document: Document) -> None:
135+
if document.text.lstrip().startswith("."):
136+
return
137+
return super().validate(document)
138+
139+
140+
class DrgnPythonRepl(PythonRepl):
141+
142+
def __init__(self, *args: Any, **kwargs: Any):
143+
super().__init__(*args, **kwargs, _validator=DrgnPythonValidator())
144+
145+
def __run_command(self, line: str) -> object:
146+
cmd_name = line.split(maxsplit=1)[0][1:]
147+
if cmd_name not in self._commands:
148+
print(f"{cmd_name}: drgn command not found")
149+
return None
150+
cmd = self._commands[cmd_name]
151+
locals = self.get_locals()
152+
prog = locals["prog"]
153+
setattr(builtins, "_", cmd(prog, line, locals))
154+
155+
def eval(self, line: str) -> object:
156+
if line.lstrip().startswith('.'):
157+
return self.__run_command(line)
158+
return super().eval(line)
159+
160+
127161
def run_interactive(
128162
prog: drgn.Program,
129163
banner_func: Optional[Callable[[str], str]] = None,
130164
globals_func: Optional[Callable[[Dict[str, Any]], Dict[str, Any]]] = None,
165+
commands_func: Optional[Callable[[Dict[str, Command]], Dict[str, Command]]] = None,
131166
quiet: bool = False,
132167
) -> None:
133168
"""
@@ -184,6 +219,12 @@ def run_interactive(
184219
if globals_func:
185220
init_globals = globals_func(init_globals)
186221

222+
commands = all_commands()
223+
if commands_func:
224+
commands = commands_func(commands)
225+
commands["help"] = help_command(commands)
226+
DrgnPythonRepl._commands = commands
227+
187228
old_path = list(sys.path)
188229
try:
189230
old_default_prog = drgn.get_default_prog()
@@ -212,6 +253,7 @@ def run_interactive(
212253

213254

214255
if __name__ == "__main__":
256+
ptpython.repl.PythonRepl = DrgnPythonRepl
215257
# Muck around with the internals of drgn: swap out run_interactive() with our
216258
# ptpython version, and then call main as if nothing happened.
217259
drgn.cli.run_interactive = run_interactive

0 commit comments

Comments
 (0)