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