> On Jun 22, 2018, at 5:20 PM, Jim Ingham <jing...@apple.com> wrote:
> 
> This is very cool!  
> 
> Could we make a base class for lldb commands in the lldb module that provides 
> register_lldb_command?  Then you wouldn't have to copy and paste this 
> boiler-plate in every command file.  Now that you have a generic way to add 
> the commands, we could just do that automatically in "command script import" 
> on every class that derives from this base when we import the module, and you 
> wouldn't need to add the __lldb_init_module either.
> 
> We could also provide a table driven way to specify the options, then have 
> the base class actually make them using opt parse.  I'd like to hide this bit 
> as much as possible, to prepare for eventually transitioning over to having 
> the options be real lldb command options.
> 
> Jim
> 
> 
>> On Jun 22, 2018, at 4:34 PM, Greg Clayton via lldb-commits 
>> <lldb-commits@lists.llvm.org> wrote:
>> 
>> Author: gclayton
>> Date: Fri Jun 22 16:34:24 2018
>> New Revision: 335401
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=335401&view=rev
>> Log:
>> Update cmdtemplate.py to use best pratices.
>> 
>> Fixes include:
>> - fix all lint errors
>> - add code that will automatically register and LLDB command classes by 
>> detecting the classes and any classes that have a "register_lldb_command" 
>> function
>> - automatically fill in the correct module name when registering commands
>> - automatically fill in the class name when registering command
>> 
>> 
>> Modified:
>>   lldb/trunk/examples/python/cmdtemplate.py
>> 
>> Modified: lldb/trunk/examples/python/cmdtemplate.py
>> URL: 
>> http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/python/cmdtemplate.py?rev=335401&r1=335400&r2=335401&view=diff
>> ==============================================================================
>> --- lldb/trunk/examples/python/cmdtemplate.py (original)
>> +++ lldb/trunk/examples/python/cmdtemplate.py Fri Jun 22 16:34:24 2018
>> @@ -1,69 +1,91 @@
>> #!/usr/bin/python
>> 
>> -#----------------------------------------------------------------------
>> +# ---------------------------------------------------------------------
>> # Be sure to add the python path that points to the LLDB shared library.
>> #
>> # # To use this in the embedded python interpreter using "lldb" just
>> # import it with the full path using the "command script import"
>> # command
>> #   (lldb) command script import /path/to/cmdtemplate.py
>> -#----------------------------------------------------------------------
>> +# ---------------------------------------------------------------------
>> 
>> +import inspect
>> import lldb
>> -import commands
>> import optparse
>> import shlex
>> +import sys
>> +
>> 
>> class FrameStatCommand:
>> -    def create_options(self):
>> +    program = 'framestats'
>> +
>> +    @classmethod
>> +    def register_lldb_command(cls, debugger, module_name):
>> +        parser = cls.create_options()
>> +        cls.__doc__ = parser.format_help()
>> +        # Add any commands contained in this module to LLDB
>> +        command = 'command script add -c %s.%s %s' % (module_name,
>> +                                                      cls.__name__,
>> +                                                      cls.program)
>> +        debugger.HandleCommand(command)
>> +        print('The "{0}" command has been installed, type "help {0}" or 
>> "{0} '
>> +              '--help" for detailed help.'.format(cls.program))
>> +
>> +    @classmethod
>> +    def create_options(cls):
>> 
>>        usage = "usage: %prog [options]"
>> -        description = '''This command is meant to be an example of how to 
>> make an LLDB command that
>> -does something useful, follows best practices, and exploits the SB API.
>> -Specifically, this command computes the aggregate and average size of the 
>> variables in the current frame
>> -and allows you to tweak exactly which variables are to be accounted in the 
>> computation.
>> -'''
>> -
>> -        # Pass add_help_option = False, since this keeps the command in 
>> line with lldb commands, 
>> -        # and we wire up "help command" to work by providing the long & 
>> short help methods below.
>> -        self.parser = optparse.OptionParser(
>> -            description = description,
>> -            prog = 'framestats',
>> -            usage = usage,
>> -            add_help_option = False)
>> +        description = ('This command is meant to be an example of how to 
>> make '
>> +                       'an LLDB command that does something useful, follows 
>> '
>> +                       'best practices, and exploits the SB API. '
>> +                       'Specifically, this command computes the aggregate '
>> +                       'and average size of the variables in the current '
>> +                       'frame and allows you to tweak exactly which 
>> variables '
>> +                       'are to be accounted in the computation.')
>> +
>> +        # Pass add_help_option = False, since this keeps the command in line
>> +        #  with lldb commands, and we wire up "help command" to work by
>> +        # providing the long & short help methods below.
>> +        parser = optparse.OptionParser(
>> +            description=description,
>> +            prog=cls.program,
>> +            usage=usage,
>> +            add_help_option=False)
>> 
>> -        self.parser.add_option(
>> +        parser.add_option(
>>            '-i',
>>            '--in-scope',
>> -            action = 'store_true',
>> -            dest = 'inscope',
>> -            help = 'in_scope_only = True',
>> -            default = True)
>> +            action='store_true',
>> +            dest='inscope',
>> +            help='in_scope_only = True',
>> +            default=True)
>> 
>> -        self.parser.add_option(
>> +        parser.add_option(
>>            '-a',
>>            '--arguments',
>> -            action = 'store_true',
>> -            dest = 'arguments',
>> -            help = 'arguments = True',
>> -            default = True)
>> +            action='store_true',
>> +            dest='arguments',
>> +            help='arguments = True',
>> +            default=True)
>> 
>> -        self.parser.add_option(
>> +        parser.add_option(
>>            '-l',
>>            '--locals',
>> -            action = 'store_true',
>> -            dest = 'locals',
>> -            help = 'locals = True',
>> -            default = True)
>> +            action='store_true',
>> +            dest='locals',
>> +            help='locals = True',
>> +            default=True)
>> 
>> -        self.parser.add_option(
>> +        parser.add_option(
>>            '-s',
>>            '--statics',
>> -            action = 'store_true',
>> -            dest = 'statics',
>> -            help = 'statics = True',
>> -            default = True)
>> - 
>> +            action='store_true',
>> +            dest='statics',
>> +            help='statics = True',
>> +            default=True)
>> +
>> +        return parser
>> +
>>    def get_short_help(self):
>>        return "Example command for use in debugging"
>> 
>> @@ -71,23 +93,25 @@ and allows you to tweak exactly which va
>>        return self.help_string
>> 
>>    def __init__(self, debugger, unused):
>> -        self.create_options()
>> +        self.parser = self.create_options()
>>        self.help_string = self.parser.format_help()
>> 
>>    def __call__(self, debugger, command, exe_ctx, result):
>>        # Use the Shell Lexer to properly parse up command options just like a
>>        # shell would
>>        command_args = shlex.split(command)
>> -        
>> +
>>        try:
>>            (options, args) = self.parser.parse_args(command_args)
>>        except:
>> -            # if you don't handle exceptions, passing an incorrect argument 
>> to the OptionParser will cause LLDB to exit
>> -            # (courtesy of OptParse dealing with argument errors by 
>> throwing SystemExit)
>> +            # if you don't handle exceptions, passing an incorrect argument 
>> to
>> +            # the OptionParser will cause LLDB to exit (courtesy of OptParse
>> +            # dealing with argument errors by throwing SystemExit)
>>            result.SetError("option parsing failed")
>>            return
>> 
>> -        # Always get program state from the SBExecutionContext passed in as 
>> exe_ctx
>> +        # Always get program state from the lldb.SBExecutionContext passed
>> +        # in as exe_ctx
>>        frame = exe_ctx.GetFrame()
>>        if not frame.IsValid():
>>            result.SetError("invalid frame")
>> @@ -108,15 +132,16 @@ and allows you to tweak exactly which va
>>            variable_type = variable.GetType()
>>            total_size = total_size + variable_type.GetByteSize()
>>            average_size = float(total_size) / variables_count
>> -            print >>result, "Your frame has %d variables. Their total size 
>> is %d bytes. The average size is %f bytes" % (
>> -                variables_count, total_size, average_size)
>> -         # not returning anything is akin to returning success
>> +            print >>result, ("Your frame has %d variables. Their total size 
>> "
>> +                             "is %d bytes. The average size is %f bytes") % 
>> (
>> +                                    variables_count, total_size, 
>> average_size)
>> +        # not returning anything is akin to returning success
>> 
>> 
>> def __lldb_init_module(debugger, dict):
>> -    # This initializer is being run from LLDB in the embedded command 
>> interpreter
>> -
>> -    # Add any commands contained in this module to LLDB
>> -    debugger.HandleCommand(
>> -        'command script add -c cmdtemplate.FrameStatCommand framestats')
>> -    print 'The "framestats" command has been installed, type "help 
>> framestats" for detailed help.'
>> +    # Register all classes that have a register_lldb_command method
>> +    for _name, cls in inspect.getmembers(sys.modules[__name__]):
>> +        if inspect.isclass(cls) and callable(getattr(cls,
>> +                                                     
>> "register_lldb_command",
>> +                                                     None)):
>> +            cls.register_lldb_command(debugger, __name__)
>> 
>> 
>> _______________________________________________
>> lldb-commits mailing list
>> lldb-commits@lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
> 

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to