xref: /llvm-project/lldb/test/API/commands/command/script/add/test_commands.py (revision 04b443e77845cd20ab5acc4356cee509316135dd)
1a69ecb24Sjimingham"""
2a69ecb24SjiminghamTest defining commands using the lldb command definitions
3a69ecb24Sjimingham"""
4a69ecb24Sjiminghamimport inspect
5a69ecb24Sjiminghamimport sys
6a69ecb24Sjiminghamimport lldb
7a69ecb24Sjiminghamfrom lldb.plugins.parsed_cmd import ParsedCommand
8a69ecb24Sjimingham
9096c530aSJonas Devlieghere
10a69ecb24Sjiminghamclass ReportingCmd(ParsedCommand):
11a69ecb24Sjimingham    def __init__(self, debugger, unused):
12a69ecb24Sjimingham        super().__init__(debugger, unused)
13a69ecb24Sjimingham
14a69ecb24Sjimingham    def __call__(self, debugger, args_array, exe_ctx, result):
15a69ecb24Sjimingham        opt_def = self.get_options_definition()
16a69ecb24Sjimingham        if len(opt_def):
17a69ecb24Sjimingham            result.AppendMessage("Options:\n")
18a69ecb24Sjimingham            for long_option, elem in opt_def.items():
19a69ecb24Sjimingham                dest = elem["dest"]
20096c530aSJonas Devlieghere                result.AppendMessage(
21*04b443e7Sjimingham                    f"{long_option} (set: {elem['_value_set']}): {object.__getattribute__(self.get_parser(), dest)}\n"
22096c530aSJonas Devlieghere                )
23a69ecb24Sjimingham        else:
24a69ecb24Sjimingham            result.AppendMessage("No options\n")
25a69ecb24Sjimingham
26a69ecb24Sjimingham        num_args = args_array.GetSize()
27a69ecb24Sjimingham        if num_args > 0:
28a69ecb24Sjimingham            result.AppendMessage(f"{num_args} arguments:")
29a69ecb24Sjimingham        for idx in range(0, num_args):
30096c530aSJonas Devlieghere            result.AppendMessage(
31096c530aSJonas Devlieghere                f"{idx}: {args_array.GetItemAtIndex(idx).GetStringValue(10000)}\n"
32096c530aSJonas Devlieghere            )
33096c530aSJonas Devlieghere
3477d131edSjimingham# Use these to make sure that get_repeat_command sends the right
3577d131edSjimingham# command.
3677d131edSjiminghamno_args_repeat = None
3777d131edSjiminghamone_arg_repeat = None
3877d131edSjiminghamtwo_arg_repeat = None
3977d131edSjimingham
40a69ecb24Sjiminghamclass NoArgsCommand(ReportingCmd):
41a69ecb24Sjimingham    program = "no-args"
42a69ecb24Sjimingham
43a69ecb24Sjimingham    def __init__(self, debugger, unused):
44a69ecb24Sjimingham        super().__init__(debugger, unused)
45a69ecb24Sjimingham
46a69ecb24Sjimingham    @classmethod
47a69ecb24Sjimingham    def register_lldb_command(cls, debugger, module_name):
48a69ecb24Sjimingham        ParsedCommand.do_register_cmd(cls, debugger, module_name)
49a69ecb24Sjimingham
50a69ecb24Sjimingham    def setup_command_definition(self):
51*04b443e7Sjimingham        ov_parser = self.get_parser()
52*04b443e7Sjimingham        ov_parser.add_option(
53a69ecb24Sjimingham            "b",
54a69ecb24Sjimingham            "bool-arg",
55a69ecb24Sjimingham            "a boolean arg, defaults to True",
56a69ecb24Sjimingham            value_type=lldb.eArgTypeBoolean,
57a69ecb24Sjimingham            groups=[1, 2],
58a69ecb24Sjimingham            dest="bool_arg",
59096c530aSJonas Devlieghere            default=True,
60a69ecb24Sjimingham        )
61a69ecb24Sjimingham
62*04b443e7Sjimingham        ov_parser.add_option(
63a69ecb24Sjimingham            "s",
64a69ecb24Sjimingham            "shlib-name",
65a69ecb24Sjimingham            "A shared library name.",
66a69ecb24Sjimingham            value_type=lldb.eArgTypeShlibName,
67a69ecb24Sjimingham            groups=[1, [3, 4]],
68a69ecb24Sjimingham            dest="shlib_name",
69096c530aSJonas Devlieghere            default=None,
70a69ecb24Sjimingham        )
71a69ecb24Sjimingham
72*04b443e7Sjimingham        ov_parser.add_option(
73a69ecb24Sjimingham            "d",
74a69ecb24Sjimingham            "disk-file-name",
75a69ecb24Sjimingham            "An on disk filename",
76a69ecb24Sjimingham            value_type=lldb.eArgTypeFilename,
77a69ecb24Sjimingham            dest="disk_file_name",
78096c530aSJonas Devlieghere            default=None,
79a69ecb24Sjimingham        )
80a69ecb24Sjimingham
81*04b443e7Sjimingham        ov_parser.add_option(
82a69ecb24Sjimingham            "l",
83a69ecb24Sjimingham            "line-num",
84a69ecb24Sjimingham            "A line number",
85a69ecb24Sjimingham            value_type=lldb.eArgTypeLineNum,
86a69ecb24Sjimingham            groups=3,
87a69ecb24Sjimingham            dest="line_num",
88096c530aSJonas Devlieghere            default=0,
89a69ecb24Sjimingham        )
90a69ecb24Sjimingham
91*04b443e7Sjimingham        ov_parser.add_option(
92a69ecb24Sjimingham            "e",
93a69ecb24Sjimingham            "enum-option",
94a69ecb24Sjimingham            "An enum, doesn't actually do anything",
95096c530aSJonas Devlieghere            enum_values=[
96096c530aSJonas Devlieghere                ["foo", "does foo things"],
97a69ecb24Sjimingham                ["bar", "does bar things"],
98096c530aSJonas Devlieghere                ["baz", "does baz things"],
99096c530aSJonas Devlieghere            ],
100a69ecb24Sjimingham            groups=4,
101a69ecb24Sjimingham            dest="enum_option",
102096c530aSJonas Devlieghere            default="foo",
103a69ecb24Sjimingham        )
104a69ecb24Sjimingham
10577d131edSjimingham    def get_repeat_command(self, command):
10677d131edSjimingham        # No auto-repeat
10777d131edSjimingham        global no_args_repeat
10877d131edSjimingham        no_args_repeat = command
10977d131edSjimingham        return ""
11077d131edSjimingham
111a69ecb24Sjimingham    def get_short_help(self):
112a69ecb24Sjimingham        return "Example command for use in debugging"
113a69ecb24Sjimingham
114a69ecb24Sjimingham    def get_long_help(self):
115a69ecb24Sjimingham        return self.help_string
116a69ecb24Sjimingham
117096c530aSJonas Devlieghere
118a69ecb24Sjiminghamclass OneArgCommandNoOptions(ReportingCmd):
119a69ecb24Sjimingham    program = "one-arg-no-opt"
120a69ecb24Sjimingham
121a69ecb24Sjimingham    def __init__(self, debugger, unused):
122a69ecb24Sjimingham        super().__init__(debugger, unused)
123a69ecb24Sjimingham
124a69ecb24Sjimingham    @classmethod
125a69ecb24Sjimingham    def register_lldb_command(cls, debugger, module_name):
126a69ecb24Sjimingham        ParsedCommand.do_register_cmd(cls, debugger, module_name)
127a69ecb24Sjimingham
128a69ecb24Sjimingham    def setup_command_definition(self):
129*04b443e7Sjimingham        ov_parser = self.get_parser()
130*04b443e7Sjimingham        ov_parser.add_argument_set(
131*04b443e7Sjimingham            [ov_parser.make_argument_element(lldb.eArgTypeSourceFile, "plain")]
132096c530aSJonas Devlieghere        )
133a69ecb24Sjimingham
13477d131edSjimingham    def get_repeat_command(self, command):
13577d131edSjimingham        # Repeat the current command
13677d131edSjimingham        global one_arg_repeat
13777d131edSjimingham        one_arg_repeat = command
13877d131edSjimingham        return None
13977d131edSjimingham
140a69ecb24Sjimingham    def get_short_help(self):
141a69ecb24Sjimingham        return "Example command for use in debugging"
142a69ecb24Sjimingham
143a69ecb24Sjimingham    def get_long_help(self):
144a69ecb24Sjimingham        return self.help_string
145a69ecb24Sjimingham
146096c530aSJonas Devlieghere
147a69ecb24Sjiminghamclass TwoArgGroupsCommand(ReportingCmd):
148a69ecb24Sjimingham    program = "two-args"
149a69ecb24Sjimingham
150a69ecb24Sjimingham    def __init__(self, debugger, unused):
151a69ecb24Sjimingham        super().__init__(debugger, unused)
152a69ecb24Sjimingham
153a69ecb24Sjimingham    @classmethod
154a69ecb24Sjimingham    def register_lldb_command(cls, debugger, module_name):
155a69ecb24Sjimingham        ParsedCommand.do_register_cmd(cls, debugger, module_name)
156a69ecb24Sjimingham
157a69ecb24Sjimingham    def setup_command_definition(self):
158*04b443e7Sjimingham        ov_parser = self.get_parser()
159*04b443e7Sjimingham        ov_parser.add_option(
160a69ecb24Sjimingham            "l",
161a69ecb24Sjimingham            "language",
162a69ecb24Sjimingham            "language defaults to None",
163a69ecb24Sjimingham            value_type=lldb.eArgTypeLanguage,
164a69ecb24Sjimingham            groups=[1, 2],
165a69ecb24Sjimingham            dest="language",
166096c530aSJonas Devlieghere            default=None,
167a69ecb24Sjimingham        )
168a69ecb24Sjimingham
169*04b443e7Sjimingham        ov_parser.add_option(
170a69ecb24Sjimingham            "c",
171a69ecb24Sjimingham            "log-channel",
172a69ecb24Sjimingham            "log channel - defaults to lldb",
173a69ecb24Sjimingham            value_type=lldb.eArgTypeLogChannel,
174a69ecb24Sjimingham            groups=[1, 3],
175a69ecb24Sjimingham            dest="log_channel",
176096c530aSJonas Devlieghere            default="lldb",
177a69ecb24Sjimingham        )
178a69ecb24Sjimingham
179*04b443e7Sjimingham        ov_parser.add_option(
180a69ecb24Sjimingham            "p",
181a69ecb24Sjimingham            "process-name",
182a69ecb24Sjimingham            "A process name, defaults to None",
183a69ecb24Sjimingham            value_type=lldb.eArgTypeProcessName,
184a69ecb24Sjimingham            dest="proc_name",
185096c530aSJonas Devlieghere            default=None,
186a69ecb24Sjimingham        )
187a69ecb24Sjimingham
188*04b443e7Sjimingham        ov_parser.add_argument_set(
189096c530aSJonas Devlieghere            [
190*04b443e7Sjimingham                ov_parser.make_argument_element(
191096c530aSJonas Devlieghere                    lldb.eArgTypeClassName, "plain", [1, 2]
192096c530aSJonas Devlieghere                ),
193*04b443e7Sjimingham                ov_parser.make_argument_element(
194096c530aSJonas Devlieghere                    lldb.eArgTypeOffset, "optional", [1, 2]
195096c530aSJonas Devlieghere                ),
196096c530aSJonas Devlieghere            ]
197096c530aSJonas Devlieghere        )
198a69ecb24Sjimingham
199*04b443e7Sjimingham        ov_parser.add_argument_set(
200096c530aSJonas Devlieghere            [
201*04b443e7Sjimingham                ov_parser.make_argument_element(
202096c530aSJonas Devlieghere                    lldb.eArgTypePythonClass, "plain", [3, 4]
203096c530aSJonas Devlieghere                ),
204*04b443e7Sjimingham                ov_parser.make_argument_element(lldb.eArgTypePid, "optional", [3, 4]),
205096c530aSJonas Devlieghere            ]
206096c530aSJonas Devlieghere        )
207a69ecb24Sjimingham
20877d131edSjimingham    def get_repeat_command(self, command):
20977d131edSjimingham        global two_arg_repeat
21077d131edSjimingham        two_arg_repeat = command
21177d131edSjimingham        return command + " THIRD_ARG"
21277d131edSjimingham
213*04b443e7Sjimingham    def handle_option_argument_completion(self, long_option, cursor_pos):
214*04b443e7Sjimingham        ov_parser = self.get_parser()
215*04b443e7Sjimingham        value = ov_parser.dest_for_option(long_option)[0 : cursor_pos + 1]
216*04b443e7Sjimingham        proc_value = ov_parser.proc_name
217*04b443e7Sjimingham        if proc_value != None:
218*04b443e7Sjimingham            new_str = value + proc_value
219*04b443e7Sjimingham            ret_arr = {"completion": new_str, "mode": "partial"}
220*04b443e7Sjimingham            return ret_arr
221*04b443e7Sjimingham
222*04b443e7Sjimingham        ret_arr = {"values": [value + "nice", value + "not_nice", value + "mediocre"]}
223*04b443e7Sjimingham        return ret_arr
224*04b443e7Sjimingham
225*04b443e7Sjimingham    def handle_argument_completion(self, args, arg_pos, cursor_pos):
226*04b443e7Sjimingham        ov_parser = self.get_parser()
227*04b443e7Sjimingham        orig_arg = args[arg_pos][0:cursor_pos]
228*04b443e7Sjimingham        if orig_arg == "correct_":
229*04b443e7Sjimingham            ret_arr = {"completion": "correct_answer"}
230*04b443e7Sjimingham            return ret_arr
231*04b443e7Sjimingham
232*04b443e7Sjimingham        if ov_parser.was_set("process-name"):
233*04b443e7Sjimingham            # No completions if proc_name was set.
234*04b443e7Sjimingham            return True
235*04b443e7Sjimingham
236*04b443e7Sjimingham        ret_arr = {
237*04b443e7Sjimingham            "values": [orig_arg + "cool", orig_arg + "yuck"],
238*04b443e7Sjimingham            "descriptions": ["good idea", "bad idea"],
239*04b443e7Sjimingham        }
240*04b443e7Sjimingham        return ret_arr
241*04b443e7Sjimingham
242a69ecb24Sjimingham    def get_short_help(self):
24377d131edSjimingham        return "This is my short help string"
244a69ecb24Sjimingham
245a69ecb24Sjimingham    def get_long_help(self):
246a69ecb24Sjimingham        return self.help_string
247a69ecb24Sjimingham
248096c530aSJonas Devlieghere
249a69ecb24Sjiminghamdef __lldb_init_module(debugger, dict):
250a69ecb24Sjimingham    # Register all classes that have a register_lldb_command method
251a69ecb24Sjimingham    for _name, cls in inspect.getmembers(sys.modules[__name__]):
252a69ecb24Sjimingham        if inspect.isclass(cls) and callable(
253a69ecb24Sjimingham            getattr(cls, "register_lldb_command", None)
254a69ecb24Sjimingham        ):
255a69ecb24Sjimingham            cls.register_lldb_command(debugger, __name__)
256