#!/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 lldb
import commands
import optparse
import shlex

def create_framestats_options():
    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.
'''
    parser = optparse.OptionParser(description=description, prog='framestats',usage=usage)
    parser.add_option('-i', '--in-scope', action='store_true', dest='inscope', help='in_scope_only = True', default=False)
    parser.add_option('-a', '--arguments', action='store_true', dest='arguments', help='arguments = True', default=False)
    parser.add_option('-l', '--locals', action='store_true', dest='locals', help='locals = True', default=False)
    parser.add_option('-s', '--statics', action='store_true', dest='statics', help='statics = True', default=False)
    return parser

def the_framestats_command(debugger, command, result, dict):
    # Use the Shell Lexer to properly parse up command options just like a 
    # shell would
    command_args = shlex.split(command)
    parser = create_framestats_options()
    try:
        (options, args) = 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)
        result.SetError ("option parsing failed")
        return
    
    # in a command - the lldb.* convenience variables are not to be used
    # and their values (if any) are undefined
    # this is the best practice to access those objects from within a command
    target = debugger.GetSelectedTarget()
    process = target.GetProcess()
    thread = process.GetSelectedThread()
    frame = thread.GetSelectedFrame()
    if not frame.IsValid():
        return "no frame here"
    # from now on, replace lldb.<thing>.whatever with <thing>.whatever
    variables_list = frame.GetVariables(options.arguments, options.locals, options.statics, options.inscope)
    variables_count = variables_list.GetSize()
    if variables_count == 0:
        print >> result, "no variables here"
        return
    total_size = 0
    for i in range(0,variables_count):
        variable = variables_list.GetValueAtIndex(i)
        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

def __lldb_init_module (debugger, dict):
    # This initializer is being run from LLDB in the embedded command interpreter    
    # Make the options so we can generate the help text for the new LLDB 
    # command line command prior to registering it with LLDB below
    parser = create_framestats_options()
    the_framestats_command.__doc__ = parser.format_help()
    # Add any commands contained in this module to LLDB
    debugger.HandleCommand('command script add -f cmdtemplate.the_framestats_command framestats')
    print 'The "framestats" command has been installed, type "help framestats" or "framestats --help" for detailed help.'
