#!/usr/bin/python

#----------------------------------------------------------------------
# This module will enable GDB remote packet logging when the 
# 'start_gdb_log' command is called with a filename to log to. When the
# 'stop_gdb_log' command is called, it will disable the logging and 
# print out statistics about how long commands took to execute and also
# will primnt ou
# 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. This can be done from the LLDB command line:
#   (lldb) command script import /path/to/gdbremote.py
# Or it can be added to your ~/.lldbinit file so this module is always
# available.
#----------------------------------------------------------------------

import commands
import optparse
import os
import shlex
import re
import tempfile

def start_gdb_log(debugger, command, result, dict):
    '''Start logging GDB remote packets by enabling logging with timestamps and 
    thread safe logging. Follow a call to this function with a call to "stop_gdb_log"
    in order to dump out the commands.'''
    global log_file
    if log_file:
        result.PutCString ('error: logging is already in progress with file "%s"', log_file)
    else:
        args_len = len(args)
        if args_len == 0:
            log_file = tempfile.mktemp()
        elif len(args) == 1:
            log_file = args[0]

        if log_file:
            debugger.HandleCommand('log enable --threadsafe --timestamp --file "%s" gdb-remote packets' % log_file);
            result.PutCString ("GDB packet logging enable with log file '%s'\nUse the 'stop_gdb_log' command to stop logging and show packet statistics." % log_file)
            return

        result.PutCString ('error: invalid log file path')
    result.PutCString (usage)

def parse_time_log(debugger, command, result, dict):
    # Any commands whose names might be followed by more valid C identifier 
    # characters must be listed here
    command_args = shlex.split(command)
    parse_time_log_args (command_args)

def parse_time_log_args(command_args):
    usage = "usage: parse_time_log [options] [<LOGFILEPATH>]"
    description='''Parse a log file that contains timestamps and convert the timestamps to delta times between log lines.'''
    parser = optparse.OptionParser(description=description, prog='parse_time_log',usage=usage)
    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
    try:
        (options, args) = parser.parse_args(command_args)
    except:
        return
    for log_file in args:
        parse_log_file (log_file, options)

def parse_log_file(file, options):
    '''Parse a log file that was contains timestamps. These logs are typically
    generated using:
    (lldb) log enable --threadsafe --timestamp --file <FILE> ....
    
    This log file will contain timestamps and this fucntion will then normalize
    those packets to be relative to the first value timestamp that is found and
    show delta times between log lines and also keep track of how long it takes
    for GDB remote commands to make a send/receive round trip. This can be
    handy when trying to figure out why some operation in the debugger is taking
    a long time during a preset set of debugger commands.'''

    print '#----------------------------------------------------------------------'
    print "# Log file: '%s'" % file
    print '#----------------------------------------------------------------------'

    timestamp_regex = re.compile('(\s*)([1-9][0-9]+\.[0-9]+)([^0-9].*)$')

    base_time = 0.0
    last_time = 0.0
    file = open(file)
    lines = file.read().splitlines()
    for line in lines:
        match = timestamp_regex.match (line)
        if match:
            curr_time = float (match.group(2))
            delta = 0.0
            if base_time:
                delta = curr_time - last_time
            else:
                base_time = curr_time

            print '%s%.6f %+.6f%s' % (match.group(1), curr_time - base_time, delta, match.group(3))
            last_time = curr_time
        else:
            print line
                    
    
    
if __name__ == '__main__':
    import sys
    parse_time_log_args (sys.argv[1:])

else:
    import lldb
    if lldb.debugger:    
        # This initializer is being run from LLDB in the embedded command interpreter
        # Add any commands contained in this module to LLDB
        lldb.debugger.HandleCommand('command script add -f delta.parse_time_log parse_time_log')
        print 'The "parse_time_log" command is now installed and ready for use, type "parse_time_log --help" for more information'
