xref: /llvm-project/lldb/test/API/commands/command/script/add/test_commands.py (revision 77d131eddb6ca9060c844fae9cb78779fa70c8f0)
1"""
2Test defining commands using the lldb command definitions
3"""
4import inspect
5import sys
6import lldb
7from lldb.plugins.parsed_cmd import ParsedCommand
8
9
10class ReportingCmd(ParsedCommand):
11    def __init__(self, debugger, unused):
12        super().__init__(debugger, unused)
13
14    def __call__(self, debugger, args_array, exe_ctx, result):
15        opt_def = self.get_options_definition()
16        if len(opt_def):
17            result.AppendMessage("Options:\n")
18            for long_option, elem in opt_def.items():
19                dest = elem["dest"]
20                result.AppendMessage(
21                    f"{long_option} (set: {elem['_value_set']}): {object.__getattribute__(self.ov_parser, dest)}\n"
22                )
23        else:
24            result.AppendMessage("No options\n")
25
26        num_args = args_array.GetSize()
27        if num_args > 0:
28            result.AppendMessage(f"{num_args} arguments:")
29        for idx in range(0, num_args):
30            result.AppendMessage(
31                f"{idx}: {args_array.GetItemAtIndex(idx).GetStringValue(10000)}\n"
32            )
33
34
35# Use these to make sure that get_repeat_command sends the right
36# command.
37no_args_repeat = None
38one_arg_repeat = None
39two_arg_repeat = None
40
41class NoArgsCommand(ReportingCmd):
42    program = "no-args"
43
44    def __init__(self, debugger, unused):
45        super().__init__(debugger, unused)
46
47    @classmethod
48    def register_lldb_command(cls, debugger, module_name):
49        ParsedCommand.do_register_cmd(cls, debugger, module_name)
50
51    def setup_command_definition(self):
52        self.ov_parser.add_option(
53            "b",
54            "bool-arg",
55            "a boolean arg, defaults to True",
56            value_type=lldb.eArgTypeBoolean,
57            groups=[1, 2],
58            dest="bool_arg",
59            default=True,
60        )
61
62        self.ov_parser.add_option(
63            "s",
64            "shlib-name",
65            "A shared library name.",
66            value_type=lldb.eArgTypeShlibName,
67            groups=[1, [3, 4]],
68            dest="shlib_name",
69            default=None,
70        )
71
72        self.ov_parser.add_option(
73            "d",
74            "disk-file-name",
75            "An on disk filename",
76            value_type=lldb.eArgTypeFilename,
77            dest="disk_file_name",
78            default=None,
79        )
80
81        self.ov_parser.add_option(
82            "l",
83            "line-num",
84            "A line number",
85            value_type=lldb.eArgTypeLineNum,
86            groups=3,
87            dest="line_num",
88            default=0,
89        )
90
91        self.ov_parser.add_option(
92            "e",
93            "enum-option",
94            "An enum, doesn't actually do anything",
95            enum_values=[
96                ["foo", "does foo things"],
97                ["bar", "does bar things"],
98                ["baz", "does baz things"],
99            ],
100            groups=4,
101            dest="enum_option",
102            default="foo",
103        )
104
105    def get_repeat_command(self, command):
106        # No auto-repeat
107        global no_args_repeat
108        no_args_repeat = command
109        return ""
110
111    def get_short_help(self):
112        return "Example command for use in debugging"
113
114    def get_long_help(self):
115        return self.help_string
116
117
118class OneArgCommandNoOptions(ReportingCmd):
119    program = "one-arg-no-opt"
120
121    def __init__(self, debugger, unused):
122        super().__init__(debugger, unused)
123
124    @classmethod
125    def register_lldb_command(cls, debugger, module_name):
126        ParsedCommand.do_register_cmd(cls, debugger, module_name)
127
128    def setup_command_definition(self):
129        self.ov_parser.add_argument_set(
130            [self.ov_parser.make_argument_element(lldb.eArgTypeSourceFile, "plain")]
131        )
132
133    def get_repeat_command(self, command):
134        # Repeat the current command
135        global one_arg_repeat
136        one_arg_repeat = command
137        return None
138
139    def get_short_help(self):
140        return "Example command for use in debugging"
141
142    def get_long_help(self):
143        return self.help_string
144
145
146class TwoArgGroupsCommand(ReportingCmd):
147    program = "two-args"
148
149    def __init__(self, debugger, unused):
150        super().__init__(debugger, unused)
151
152    @classmethod
153    def register_lldb_command(cls, debugger, module_name):
154        ParsedCommand.do_register_cmd(cls, debugger, module_name)
155
156    def setup_command_definition(self):
157        self.ov_parser.add_option(
158            "l",
159            "language",
160            "language defaults to None",
161            value_type=lldb.eArgTypeLanguage,
162            groups=[1, 2],
163            dest="language",
164            default=None,
165        )
166
167        self.ov_parser.add_option(
168            "c",
169            "log-channel",
170            "log channel - defaults to lldb",
171            value_type=lldb.eArgTypeLogChannel,
172            groups=[1, 3],
173            dest="log_channel",
174            default="lldb",
175        )
176
177        self.ov_parser.add_option(
178            "p",
179            "process-name",
180            "A process name, defaults to None",
181            value_type=lldb.eArgTypeProcessName,
182            dest="proc_name",
183            default=None,
184        )
185
186        self.ov_parser.add_argument_set(
187            [
188                self.ov_parser.make_argument_element(
189                    lldb.eArgTypeClassName, "plain", [1, 2]
190                ),
191                self.ov_parser.make_argument_element(
192                    lldb.eArgTypeOffset, "optional", [1, 2]
193                ),
194            ]
195        )
196
197        self.ov_parser.add_argument_set(
198            [
199                self.ov_parser.make_argument_element(
200                    lldb.eArgTypePythonClass, "plain", [3, 4]
201                ),
202                self.ov_parser.make_argument_element(
203                    lldb.eArgTypePid, "optional", [3, 4]
204                ),
205            ]
206        )
207
208    def get_repeat_command(self, command):
209        global two_arg_repeat
210        two_arg_repeat = command
211        return command + " THIRD_ARG"
212
213    def get_short_help(self):
214        return "This is my short help string"
215
216    def get_long_help(self):
217        return self.help_string
218
219
220def __lldb_init_module(debugger, dict):
221    # Register all classes that have a register_lldb_command method
222    for _name, cls in inspect.getmembers(sys.modules[__name__]):
223        if inspect.isclass(cls) and callable(
224            getattr(cls, "register_lldb_command", None)
225        ):
226            cls.register_lldb_command(debugger, __name__)
227