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