#!/bin/env python
"""
A gdb-compatible frontend for lldb that implements just enough
commands to run the tests in the debuginfo-tests repository with lldb.
"""

# ----------------------------------------------------------------------
# Auto-detect lldb python module.
import commands, platform, os,  sys
try:
    # Just try for LLDB in case PYTHONPATH is already correctly setup.
    import lldb
except ImportError:
    lldb_python_dirs = list()
    # lldb is not in the PYTHONPATH, try some defaults for the current platform.
    platform_system = platform.system()
    if platform_system == 'Darwin':
        # On Darwin, try the currently selected Xcode directory
        xcode_dir = commands.getoutput("xcode-select --print-path")
        if xcode_dir:
            lldb_python_dirs.append(os.path.realpath(xcode_dir +
'/../SharedFrameworks/LLDB.framework/Resources/Python'))
            lldb_python_dirs.append(xcode_dir +
'/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
        lldb_python_dirs.append(
'/System/Library/PrivateFrameworks/LLDB.framework/Resources/Python')
    success = False
    for lldb_python_dir in lldb_python_dirs:
        if os.path.exists(lldb_python_dir):
            if not (sys.path.__contains__(lldb_python_dir)):
                sys.path.append(lldb_python_dir)
                try:
                    import lldb
                except ImportError:
                    pass
                else:
                    print 'imported lldb from: "%s"' % (lldb_python_dir)
                    success = True
                    break
    if not success:
        print "error: couldn't locate the 'lldb' module, please set PYTHONPATH correctly"
        sys.exit(1)
# ----------------------------------------------------------------------

# Command line option handling.
import argparse
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--quiet', '-q', action="store_true", help='ignored')
parser.add_argument('-batch', action="store_true",
                    help='exit after processing comand line')
parser.add_argument('-n', action="store_true", help='ignore .lldb file')
parser.add_argument('-x', dest='script', type=file, help='execute commands from file')
parser.add_argument("target", help="the program to debug")
args = parser.parse_args()


# Create a new debugger instance.
debugger = lldb.SBDebugger.Create()
debugger.SkipLLDBInitFiles(args.n)

# Make sure to clean up the debugger on exit.
import atexit
def on_exit():
    debugger.Terminate()
atexit.register(on_exit)

# Don't return from lldb function calls until the process stops.
debugger.SetAsync(False)

# Create a target from a file and arch.
arch = os.popen("file "+args.target).read().split()[-1]
target = debugger.CreateTargetWithFileAndArch(args.target, arch)

if not target:
    print "Could not create target", args.target
    sys.exit(1)

if not args.script:
    print "Interactive mode is not implemented."
    sys.exit(1)

import re
for command in args.script:
    # Strip newline and whitespaces and split into words.
    cmd = command[:-1].strip().split()
    if not cmd:
        continue

    print '> %s'% command[:-1]

    try:
        if re.match('^r|(run)$', cmd[0]):
            error = lldb.SBError()
            launchinfo = lldb.SBLaunchInfo([])
            launchinfo.SetWorkingDirectory(os.getcwd())
            process = target.Launch(launchinfo, error)
            print error
            if not process or error.fail:
                state = process.GetState()
                print "State = %d" % state
                print """
ERROR: Could not launch process.
NOTE: There are several reasons why this may happen:
  * Root needs to run "DevToolsSecurity --enable".
  * Older versions of lldb cannot launch more than one process simultaneously.
"""
                sys.exit(1)

        elif re.match('^b|(break)$', cmd[0]) and len(cmd) == 2:
            if re.match('[0-9]+', cmd[1]):
                # b line
                mainfile = target.FindFunctions('main')[0].compile_unit.file
                print target.BreakpointCreateByLocation(mainfile, int(cmd[1]))
            else:
                # b file:line
                file, line = cmd[1].split(':')
                print target.BreakpointCreateByLocation(file, int(line))

        elif re.match('^ptype$', cmd[0]) and len(cmd) == 2:
            # GDB's ptype has multiple incarnations depending on its
            # argument (global variable, function, type).  The definition
            # here is for looking up the signature of a function and only
            # if that fails it looks for a type with that name.
            # Type lookup in LLDB would be "image lookup --type".
            for elem in target.FindFunctions(cmd[1]):
                print elem.function.type
                continue
            print target.FindFirstType(cmd[1])

        elif re.match('^po$', cmd[0]) and len(cmd) > 1:
            try:
                opts = lldb.SBExpressionOptions()
                opts.SetFetchDynamicValue(True)
                opts.SetCoerceResultToId(True)
                print target.EvaluateExpression(' '.join(cmd[1:]), opts)
            except:
                # FIXME: This is a fallback path for the lab.llvm.org
                # buildbot running OS X 10.7; it should be removed.
                thread = process.GetThreadAtIndex(0)
                frame = thread.GetFrameAtIndex(0)
                print frame.EvaluateExpression(' '.join(cmd[1:]))

        elif re.match('^p|(print)$', cmd[0]) and len(cmd) > 1:
            thread = process.GetThreadAtIndex(0)
            frame = thread.GetFrameAtIndex(0)
            print frame.EvaluateExpression(' '.join(cmd[1:]))

        elif re.match('^n|(next)$', cmd[0]):
            thread = process.GetThreadAtIndex(0)
            thread.StepOver()

        elif re.match('^q|(quit)$', cmd[0]):
            sys.exit(0)

        else:
            print debugger.HandleCommand(' '.join(cmd))

    except SystemExit:
        raise
    except:
        print 'Could not handle the command "%s"' % ' '.join(cmd)

