brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · db30279 Raw
264 lines · python
1"""2Test defining commands using the lldb command definitions3"""4import inspect5import sys6import lldb7from lldb.plugins.parsed_cmd import ParsedCommand8 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                if "value_type" in elem:20                    print(f"Looking at {long_option} - {elem}")21                    dest = elem["dest"]22                    result.AppendMessage(23                        f"{long_option} (set: {elem['_value_set']}): {object.__getattribute__(self.get_parser(), dest)}\n"24                    )25                else:26                    result.AppendMessage(27                        f"{long_option} (set: {elem['_value_set']}): flag value\n"28                    )29        else:30            result.AppendMessage("No options\n")31 32        num_args = args_array.GetSize()33        if num_args > 0:34            result.AppendMessage(f"{num_args} arguments:")35        for idx in range(0, num_args):36            result.AppendMessage(37                f"{idx}: {args_array.GetItemAtIndex(idx).GetStringValue(10000)}\n"38            )39 40# Use these to make sure that get_repeat_command sends the right41# command.42no_args_repeat = None43one_arg_repeat = None44two_arg_repeat = None45 46class NoArgsCommand(ReportingCmd):47    program = "no-args"48 49    def __init__(self, debugger, unused):50        super().__init__(debugger, unused)51 52    @classmethod53    def register_lldb_command(cls, debugger, module_name):54        ParsedCommand.do_register_cmd(cls, debugger, module_name)55 56    def setup_command_definition(self):57        ov_parser = self.get_parser()58        ov_parser.add_option(59            "b",60            "bool-arg",61            "a boolean arg, defaults to True",62            value_type=lldb.eArgTypeBoolean,63            groups=[1, 2],64            dest="bool_arg",65            default=True,66        )67 68        ov_parser.add_option(69            "s",70            "shlib-name",71            "A shared library name.",72            value_type=lldb.eArgTypeShlibName,73            groups=[1, [3, 4]],74            dest="shlib_name",75            default=None,76        )77 78        ov_parser.add_option(79            "d",80            "disk-file-name",81            "An on disk filename",82            value_type=lldb.eArgTypeFilename,83            dest="disk_file_name",84            default=None,85        )86 87        ov_parser.add_option("f", "flag-value", "This is a flag value")88 89        ov_parser.add_option(90            "l",91            "line-num",92            "A line number",93            value_type=lldb.eArgTypeLineNum,94            groups=3,95            dest="line_num",96            default=0,97        )98 99        ov_parser.add_option(100            "e",101            "enum-option",102            "An enum, doesn't actually do anything",103            enum_values=[104                ["foo", "does foo things"],105                ["bar", "does bar things"],106                ["baz", "does baz things"],107            ],108            groups=4,109            dest="enum_option",110            default="foo",111        )112 113    def get_repeat_command(self, command):114        # No auto-repeat115        global no_args_repeat116        no_args_repeat = command117        return ""118 119    def get_short_help(self):120        return "Example command for use in debugging"121 122    def get_long_help(self):123        return self.help_string124 125 126class OneArgCommandNoOptions(ReportingCmd):127    program = "one-arg-no-opt"128 129    def __init__(self, debugger, unused):130        super().__init__(debugger, unused)131 132    @classmethod133    def register_lldb_command(cls, debugger, module_name):134        ParsedCommand.do_register_cmd(cls, debugger, module_name)135 136    def setup_command_definition(self):137        ov_parser = self.get_parser()138        ov_parser.add_argument_set(139            [ov_parser.make_argument_element(lldb.eArgTypeSourceFile, "plain")]140        )141 142    def get_repeat_command(self, command):143        # Repeat the current command144        global one_arg_repeat145        one_arg_repeat = command146        return None147 148    def get_short_help(self):149        return "Example command for use in debugging"150 151    def get_long_help(self):152        return self.help_string153 154 155class TwoArgGroupsCommand(ReportingCmd):156    program = "two-args"157 158    def __init__(self, debugger, unused):159        super().__init__(debugger, unused)160 161    @classmethod162    def register_lldb_command(cls, debugger, module_name):163        ParsedCommand.do_register_cmd(cls, debugger, module_name)164 165    def setup_command_definition(self):166        ov_parser = self.get_parser()167        ov_parser.add_option(168            "l",169            "language",170            "language defaults to None",171            value_type=lldb.eArgTypeLanguage,172            groups=[1, 2],173            dest="language",174            default=None,175        )176 177        ov_parser.add_option(178            "c",179            "log-channel",180            "log channel - defaults to lldb",181            value_type=lldb.eArgTypeLogChannel,182            groups=[1, 3],183            dest="log_channel",184            default="lldb",185        )186 187        ov_parser.add_option(188            "p",189            "process-name",190            "A process name, defaults to None",191            value_type=lldb.eArgTypeProcessName,192            dest="proc_name",193            default=None,194        )195 196        ov_parser.add_argument_set(197            [198                ov_parser.make_argument_element(199                    lldb.eArgTypeClassName, "plain", [1, 2]200                ),201                ov_parser.make_argument_element(202                    lldb.eArgTypeOffset, "optional", [1, 2]203                ),204            ]205        )206 207        ov_parser.add_argument_set(208            [209                ov_parser.make_argument_element(210                    lldb.eArgTypePythonClass, "plain", [3, 4]211                ),212                ov_parser.make_argument_element(lldb.eArgTypePid, "optional", [3, 4]),213            ]214        )215 216    def get_repeat_command(self, command):217        global two_arg_repeat218        two_arg_repeat = command219        return command + " THIRD_ARG"220 221    def handle_option_argument_completion(self, long_option, cursor_pos):222        ov_parser = self.get_parser()223        value = ov_parser.dest_for_option(long_option)[0 : cursor_pos + 1]224        proc_value = ov_parser.proc_name225        if proc_value != None:226            new_str = value + proc_value227            ret_arr = {"completion": new_str, "mode": "partial"}228            return ret_arr229 230        ret_arr = {"values": [value + "nice", value + "not_nice", value + "mediocre"]}231        return ret_arr232 233    def handle_argument_completion(self, args, arg_pos, cursor_pos):234        ov_parser = self.get_parser()235        orig_arg = args[arg_pos][0:cursor_pos]236        if orig_arg == "correct_":237            ret_arr = {"completion": "correct_answer"}238            return ret_arr239 240        if ov_parser.was_set("process-name"):241            # No completions if proc_name was set.242            return True243 244        ret_arr = {245            "values": [orig_arg + "cool", orig_arg + "yuck"],246            "descriptions": ["good idea", "bad idea"],247        }248        return ret_arr249 250    def get_short_help(self):251        return "This is my short help string"252 253    def get_long_help(self):254        return self.help_string255 256 257def __lldb_init_module(debugger, dict):258    # Register all classes that have a register_lldb_command method259    for _name, cls in inspect.getmembers(sys.modules[__name__]):260        if inspect.isclass(cls) and callable(261            getattr(cls, "register_lldb_command", None)262        ):263            cls.register_lldb_command(debugger, __name__)264