[AArch64] Fix SDNode type mismatches between *.td files and ISel (#116523)
[llvm-project.git] / lldb / examples / python / templates / parsed_cmd.py
blob13d6eae405c08ddcb50590e4e4fd6f1649d54f10
1 """
2 This module implements a couple of utility classes to make writing
3 lldb parsed commands more Pythonic.
4 The way to use it is to make a class for your command that inherits from ParsedCommandBase.
5 That will make an LLDBOptionValueParser which you will use for your
6 option definition, and to fetch option values for the current invocation
7 of your command. For concision, I'll call this the `OVParser`.
8 Access to the `OVParser` is through:
10 ParsedCommandBase.get_parser()
12 Next, implement setup_command_definition() in your new command class, and call:
14 self.get_parser().add_option()
16 to add all your options. The order doesn't matter for options, lldb will sort them
17 alphabetically for you when it prints help.
19 Similarly you can define the arguments with:
21 self.get_parser().add_argument()
23 At present, lldb doesn't do as much work as it should verifying arguments, it
24 only checks that commands that take no arguments don't get passed arguments.
26 Then implement the execute function for your command as:
28 def __call__(self, debugger, args_list, exe_ctx, result):
30 The arguments will be a list of strings.
32 You can access the option values using the 'dest' string you passed in when defining the option.
33 And if you need to know whether a given option was set by the user or not, you can
34 use the was_set API.
36 So for instance, if you have an option whose "dest" is "my_option", then:
38 self.get_parser().my_option
40 will fetch the value, and:
42 self.get_parser().was_set("my_option")
44 will return True if the user set this option, and False if it was left at its default
45 value.
47 Custom Completions:
49 You can also implement custom completers for your custom command, either for the
50 arguments to your command or to the option values in your command. If you use enum
51 values or if your option/argument uses is one of the types we have completers for,
52 you should not need to do this. But if you have your own completeable types, or if
53 you want completion of one option to be conditioned by other options on the command
54 line, you can use this interface to take over the completion.
56 You can choose to add a completion for the option values defined for your command,
57 or for the arguments, separately. For the option values, define:
59 def handle_option_argument_completion(self, long_option, cursor_pos):
61 The line to be completed will be parsed up to the option containint the cursor position,
62 and the values will be set in the OptionValue parser object. long_option will be
63 the option name containing the cursor, and cursor_pos will be the position of the cursor
64 in that option's value. You can call the `OVParser` method: `dest_for_option(long_option)`
65 to get the value for that option. The other options that came before the cursor in the command
66 line will also be set in the `OVParser` when the completion handler is called.
68 For argument values, define:
70 def handle_argument_completion(self, args, arg_pos, cursor_pos):
72 Again, the command line will be parsed up to the cursor position, and all the options
73 before the cursor pose will be set in the `OVParser`. args is a python list of the
74 arguments, arg_pos is the index of the argument with the cursor, and cursor_pos is
75 the position of the cursor in the argument.
77 In both cases, the return value determines the completion.
79 Return False to mean "Not Handled" - in which case lldb will fall back on the
80 standard completion machinery.
82 Return True to mean "Handled with no completions".
84 If there is a single unique completion, return a Python dictionary with two elements:
86 return {"completion" : "completed_value", "mode" : <"partial", "complete">}
88 If the mode is "partial", then the completion is to a common base, if it is "complete"
89 then the argument is considered done - mostly meaning lldb will put a space after the
90 completion string. "complete" is the default if no "mode" is specified.
92 If there are multiple completion options, then return:
94 return {"values" : ["option1", "option2"]}
96 Optionally, you can return a parallel array of "descriptions" which the completer will
97 print alongside the options:
99 return {"values" : ["option1", "option2"], "descriptions" : ["the first option", "the second option"]}
101 The cmdtemplate example currently uses the parsed command infrastructure:
103 llvm-project/lldb/examples/python/cmdtemplate.py
105 There are also a few example commands in the lldb testsuite at:
107 llvm-project/lldb/test/API/commands/command/script/add/test_commands.py
109 import inspect
110 import lldb
111 import sys
112 from abc import abstractmethod
114 # Some methods to translate common value types. Should return a
115 # tuple of the value and an error value (True => error) if the
116 # type can't be converted. These are called internally when the
117 # command line is parsed into the 'dest' properties, you should
118 # not need to call them directly.
119 # FIXME: Need a way to push the conversion error string back to lldb.
120 def to_bool(in_value):
121 error = True
122 value = False
123 if type(in_value) != str or len(in_value) == 0:
124 return (value, error)
126 low_in = in_value.lower()
127 if low_in in ["y", "yes", "t", "true", "1"]:
128 value = True
129 error = False
131 if not value and low_in in ["n", "no", "f", "false", "0"]:
132 value = False
133 error = False
135 return (value, error)
137 def to_int(in_value):
138 #FIXME: Not doing errors yet...
139 return (int(in_value), False)
141 def to_unsigned(in_value):
142 # FIXME: find an unsigned converter...
143 # And handle errors.
144 return (int(in_value), False)
146 translators = {
147 lldb.eArgTypeBoolean : to_bool,
148 lldb.eArgTypeBreakpointID : to_unsigned,
149 lldb.eArgTypeByteSize : to_unsigned,
150 lldb.eArgTypeCount : to_unsigned,
151 lldb.eArgTypeFrameIndex : to_unsigned,
152 lldb.eArgTypeIndex : to_unsigned,
153 lldb.eArgTypeLineNum : to_unsigned,
154 lldb.eArgTypeNumLines : to_unsigned,
155 lldb.eArgTypeNumberPerLine : to_unsigned,
156 lldb.eArgTypeOffset : to_int,
157 lldb.eArgTypeThreadIndex : to_unsigned,
158 lldb.eArgTypeUnsignedInteger : to_unsigned,
159 lldb.eArgTypeWatchpointID : to_unsigned,
160 lldb.eArgTypeColumnNum : to_unsigned,
161 lldb.eArgTypeRecognizerID : to_unsigned,
162 lldb.eArgTypeTargetID : to_unsigned,
163 lldb.eArgTypeStopHookID : to_unsigned
166 def translate_value(value_type, value):
167 try:
168 return translators[value_type](value)
169 except KeyError:
170 # If we don't have a translator, return the string value.
171 return (value, False)
173 class LLDBOptionValueParser:
175 This class holds the option definitions for the command, and when
176 the command is run, you can ask the parser for the current values. """
178 def __init__(self):
179 # This is a dictionary of dictionaries. The key is the long option
180 # name, and the value is the rest of the definition.
181 self.options_dict = {}
182 self.args_array = []
185 # FIXME: would this be better done on the C++ side?
186 # The common completers are missing some useful ones.
187 # For instance there really should be a common Type completer
188 # And an "lldb command name" completer.
189 completion_table = {
190 lldb.eArgTypeAddressOrExpression : lldb.eVariablePathCompletion,
191 lldb.eArgTypeArchitecture : lldb.eArchitectureCompletion,
192 lldb.eArgTypeBreakpointID : lldb.eBreakpointCompletion,
193 lldb.eArgTypeBreakpointIDRange : lldb.eBreakpointCompletion,
194 lldb.eArgTypeBreakpointName : lldb.eBreakpointNameCompletion,
195 lldb.eArgTypeClassName : lldb.eSymbolCompletion,
196 lldb.eArgTypeDirectoryName : lldb.eDiskDirectoryCompletion,
197 lldb.eArgTypeExpression : lldb.eVariablePathCompletion,
198 lldb.eArgTypeExpressionPath : lldb.eVariablePathCompletion,
199 lldb.eArgTypeFilename : lldb.eDiskFileCompletion,
200 lldb.eArgTypeFrameIndex : lldb.eFrameIndexCompletion,
201 lldb.eArgTypeFunctionName : lldb.eSymbolCompletion,
202 lldb.eArgTypeFunctionOrSymbol : lldb.eSymbolCompletion,
203 lldb.eArgTypeLanguage : lldb.eTypeLanguageCompletion,
204 lldb.eArgTypePath : lldb.eDiskFileCompletion,
205 lldb.eArgTypePid : lldb.eProcessIDCompletion,
206 lldb.eArgTypeProcessName : lldb.eProcessNameCompletion,
207 lldb.eArgTypeRegisterName : lldb.eRegisterCompletion,
208 lldb.eArgTypeRunArgs : lldb.eDiskFileCompletion,
209 lldb.eArgTypeShlibName : lldb.eModuleCompletion,
210 lldb.eArgTypeSourceFile : lldb.eSourceFileCompletion,
211 lldb.eArgTypeSymbol : lldb.eSymbolCompletion,
212 lldb.eArgTypeThreadIndex : lldb.eThreadIndexCompletion,
213 lldb.eArgTypeVarName : lldb.eVariablePathCompletion,
214 lldb.eArgTypePlatform : lldb.ePlatformPluginCompletion,
215 lldb.eArgTypeWatchpointID : lldb.eWatchpointIDCompletion,
216 lldb.eArgTypeWatchpointIDRange : lldb.eWatchpointIDCompletion,
217 lldb.eArgTypeModuleUUID : lldb.eModuleUUIDCompletion,
218 lldb.eArgTypeStopHookID : lldb.eStopHookIDCompletion
221 @classmethod
222 def determine_completion(cls, arg_type):
223 return cls.completion_table.get(arg_type, lldb.eNoCompletion)
225 def add_argument_set(self, arguments):
226 self.args_array.append(arguments)
228 def get_option_element(self, long_name):
229 return self.options_dict.get(long_name, None)
231 def is_enum_opt(self, opt_name):
232 elem = self.get_option_element(opt_name)
233 if not elem:
234 return False
235 return "enum_values" in elem
237 def option_parsing_started(self):
238 """ This makes the ivars for all the "dest" values in the array and gives them
239 their default values. You should not have to call this by hand, though if
240 you have some option that needs to do some work when a new command invocation
241 starts, you can override this to handle your special option. """
242 for key, elem in self.options_dict.items():
243 elem['_value_set'] = False
244 try:
245 object.__setattr__(self, elem["dest"], elem["default"])
246 except AttributeError:
247 # It isn't an error not to have a "dest" variable name, you'll
248 # just have to manage this option's value on your own.
249 continue
251 def set_enum_value(self, enum_values, input):
252 """ This sets the value for an enum option, you should not have to call this
253 by hand. """
254 candidates = []
255 for candidate in enum_values:
256 # The enum_values are a two element list of value & help string.
257 value = candidate[0]
258 if value.startswith(input):
259 candidates.append(value)
261 if len(candidates) == 1:
262 return (candidates[0], False)
263 else:
264 return (input, True)
266 def set_option_value(self, exe_ctx, opt_name, opt_value):
267 """ This sets a single option value. This will handle most option
268 value types, but if you have an option that has some complex behavior,
269 you can override this to implement that behavior, and then pass the
270 rest of the options to the base class implementation. """
271 elem = self.get_option_element(opt_name)
272 if not elem:
273 return False
275 if "enum_values" in elem:
276 (value, error) = self.set_enum_value(elem["enum_values"], opt_value)
277 else:
278 (value, error) = translate_value(elem["value_type"], opt_value)
280 if error:
281 return False
283 object.__setattr__(self, elem["dest"], value)
284 elem["_value_set"] = True
285 return True
287 def was_set(self, opt_name):
288 """Call this in the __call__ method of your command to determine
289 whether this option was set on the command line. It is sometimes
290 useful to know whether an option has the default value because the
291 user set it explicitly (was_set -> True) or not.
292 You can also call this in a handle_completion method, but it will
293 currently only report true values for the options mentioned
294 BEFORE the cursor point in the command line.
297 elem = self.get_option_element(opt_name)
298 if not elem:
299 return False
300 try:
301 return elem["_value_set"]
302 except AttributeError:
303 return False
305 def dest_for_option(self, opt_name):
306 """This will return the value of the dest variable you defined for opt_name.
307 Mostly useful for handle_completion where you get passed the long option.
309 elem = self.get_option_element(opt_name)
310 if not elem:
311 return None
312 value = self.__dict__[elem["dest"]]
313 return value
315 def add_option(self, short_option, long_option, help, default,
316 dest = None, required=False, groups = None,
317 value_type=lldb.eArgTypeNone, completion_type=None,
318 enum_values=None):
320 short_option: one character, must be unique, not required
321 long_option: no spaces, must be unique, required
322 help: a usage string for this option, will print in the command help
323 default: the initial value for this option (if it has a value)
324 dest: the name of the property that gives you access to the value for
325 this value. Defaults to the long option if not provided.
326 required: if true, this option must be provided or the command will error out
327 groups: Which "option groups" does this option belong to. This can either be
328 a simple list (e.g. [1, 3, 4, 5]) or you can specify ranges by sublists:
329 so [1, [3,5]] is the same as [1, 3, 4, 5].
330 value_type: one of the lldb.eArgType enum values. Some of the common arg
331 types also have default completers, which will be applied automatically.
332 completion_type: currently these are values form the lldb.CompletionType enum. If
333 you need custom completions, implement handle_option_argument_completion.
334 enum_values: An array of duples: ["element_name", "element_help"]. If provided,
335 only one of the enum elements is allowed. The value will be the
336 element_name for the chosen enum element as a string.
338 if not dest:
339 dest = long_option
341 if not completion_type:
342 completion_type = self.determine_completion(value_type)
344 dict = {"short_option" : short_option,
345 "required" : required,
346 "help" : help,
347 "value_type" : value_type,
348 "completion_type" : completion_type,
349 "dest" : dest,
350 "default" : default}
352 if enum_values:
353 dict["enum_values"] = enum_values
354 if groups:
355 dict["groups"] = groups
357 self.options_dict[long_option] = dict
359 def make_argument_element(self, arg_type, repeat = "optional", groups = None):
360 element = {"arg_type" : arg_type, "repeat" : repeat}
361 if groups:
362 element["groups"] = groups
363 return element
365 class ParsedCommand:
366 def __init__(self, debugger, unused):
367 self.debugger = debugger
368 self.ov_parser = LLDBOptionValueParser()
369 self.setup_command_definition()
371 def get_options_definition(self):
372 return self.get_parser().options_dict
374 def get_flags(self):
375 return 0
377 def get_args_definition(self):
378 return self.get_parser().args_array
380 # The base class will handle calling these methods
381 # when appropriate.
383 def option_parsing_started(self):
384 self.get_parser().option_parsing_started()
386 def set_option_value(self, exe_ctx, opt_name, opt_value):
387 return self.get_parser().set_option_value(exe_ctx, opt_name, opt_value)
389 def get_parser(self):
390 """Returns the option value parser for this command.
391 When defining the command, use the parser to add
392 argument and option definitions to the command.
393 When you are in the command callback, the parser
394 gives you access to the options passes to this
395 invocation"""
397 return self.ov_parser
399 # These are the two "pure virtual" methods:
400 @abstractmethod
401 def __call__(self, debugger, args_array, exe_ctx, result):
402 """This is the command callback. The option values are
403 provided by the 'dest' properties on the parser.
405 args_array: This is the list of arguments provided.
406 exe_ctx: Gives the SBExecutionContext on which the
407 command should operate.
408 result: Any results of the command should be
409 written into this SBCommandReturnObject.
411 raise NotImplementedError()
413 @abstractmethod
414 def setup_command_definition(self):
415 """This will be called when your command is added to
416 the command interpreter. Here is where you add your
417 options and argument definitions for the command."""
418 raise NotImplementedError()
420 @staticmethod
421 def do_register_cmd(cls, debugger, module_name):
422 """ Add any commands contained in this module to LLDB """
423 command = "command script add -o -p -c %s.%s %s" % (
424 module_name,
425 cls.__name__,
426 cls.program,
428 debugger.HandleCommand(command)
429 print(
430 'The "{0}" command has been installed, type "help {0}"'
431 'for detailed help.'.format(cls.program)