//===-- ScriptInterpreterPython.cpp -----------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// In order to guarantee correct working with Python, Python.h *MUST* be
// the *FIRST* header file included here.
#ifdef LLDB_DISABLE_PYTHON

// Python is disabled in this build

#else

#include "lldb/lldb-python.h"
#include "lldb/Interpreter/ScriptInterpreterPython.h"

#include <stdlib.h>
#include <stdio.h>

#include <string>

#include "lldb/API/SBValue.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/WatchpointOptions.h"
#include "lldb/Core/Communication.h"
#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/PythonDataObjects.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;


static ScriptInterpreter::SWIGInitCallback g_swig_init_callback = nullptr;
static ScriptInterpreter::SWIGBreakpointCallbackFunction g_swig_breakpoint_callback = nullptr;
static ScriptInterpreter::SWIGWatchpointCallbackFunction g_swig_watchpoint_callback = nullptr;
static ScriptInterpreter::SWIGPythonTypeScriptCallbackFunction g_swig_typescript_callback = nullptr;
static ScriptInterpreter::SWIGPythonCreateSyntheticProvider g_swig_synthetic_script = nullptr;
static ScriptInterpreter::SWIGPythonCalculateNumChildren g_swig_calc_children = nullptr;
static ScriptInterpreter::SWIGPythonGetChildAtIndex g_swig_get_child_index = nullptr;
static ScriptInterpreter::SWIGPythonGetIndexOfChildWithName g_swig_get_index_child = nullptr;
static ScriptInterpreter::SWIGPythonCastPyObjectToSBValue g_swig_cast_to_sbvalue  = nullptr;
static ScriptInterpreter::SWIGPythonGetValueObjectSPFromSBValue g_swig_get_valobj_sp_from_sbvalue = nullptr;
static ScriptInterpreter::SWIGPythonUpdateSynthProviderInstance g_swig_update_provider = nullptr;
static ScriptInterpreter::SWIGPythonMightHaveChildrenSynthProviderInstance g_swig_mighthavechildren_provider = nullptr;
static ScriptInterpreter::SWIGPythonCallCommand g_swig_call_command = nullptr;
static ScriptInterpreter::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr;
static ScriptInterpreter::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Thread g_swig_run_script_keyword_thread = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Target g_swig_run_script_keyword_target = nullptr;
static ScriptInterpreter::SWIGPythonScriptKeyword_Frame g_swig_run_script_keyword_frame = nullptr;
static ScriptInterpreter::SWIGPython_GetDynamicSetting g_swig_plugin_get = nullptr;

static std::string
ReadPythonBacktrace (PyObject* py_backtrace);

ScriptInterpreterPython::Locker::Locker (ScriptInterpreterPython *py_interpreter,
                                         uint16_t on_entry,
                                         uint16_t on_leave,
                                         FILE *in,
                                         FILE *out,
                                         FILE *err) :
    ScriptInterpreterLocker (),
    m_teardown_session( (on_leave & TearDownSession) == TearDownSession ),
    m_python_interpreter(py_interpreter)
{
    DoAcquireLock();
    if ((on_entry & InitSession) == InitSession)
    {
        if (DoInitSession(on_entry, in, out, err) == false)
        {
            // Don't teardown the session if we didn't init it.
            m_teardown_session = false;
        }
    }
}

bool
ScriptInterpreterPython::Locker::DoAcquireLock()
{
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
    m_GILState = PyGILState_Ensure();
    if (log)
        log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
    
    // we need to save the thread state when we first start the command
    // because we might decide to interrupt it while some action is taking
    // place outside of Python (e.g. printing to screen, waiting for the network, ...)
    // in that case, _PyThreadState_Current will be NULL - and we would be unable
    // to set the asynchronous exception - not a desirable situation
    m_python_interpreter->SetThreadState (_PyThreadState_Current);
    return true;
}

bool
ScriptInterpreterPython::Locker::DoInitSession(uint16_t on_entry_flags, FILE *in, FILE *out, FILE *err)
{
    if (!m_python_interpreter)
        return false;
    return m_python_interpreter->EnterSession (on_entry_flags, in, out, err);
}

bool
ScriptInterpreterPython::Locker::DoFreeLock()
{
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
    if (log)
        log->Printf("Releasing PyGILState. Returning to state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
    PyGILState_Release(m_GILState);
    return true;
}

bool
ScriptInterpreterPython::Locker::DoTearDownSession()
{
    if (!m_python_interpreter)
        return false;
    m_python_interpreter->LeaveSession ();
    return true;
}

ScriptInterpreterPython::Locker::~Locker()
{
    if (m_teardown_session)
        DoTearDownSession();
    DoFreeLock();
}


ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interpreter) :
    ScriptInterpreter (interpreter, eScriptLanguagePython),
    IOHandlerDelegateMultiline("DONE"),
    m_saved_stdin (),
    m_saved_stdout (),
    m_saved_stderr (),
    m_main_module (),
    m_lldb_module (),
    m_session_dict (false),     // Don't create an empty dictionary, leave it invalid
    m_sys_module_dict (false),  // Don't create an empty dictionary, leave it invalid
    m_run_one_line_function (),
    m_run_one_line_str_global (),
    m_dictionary_name (interpreter.GetDebugger().GetInstanceName().AsCString()),
    m_terminal_state (),
    m_active_io_handler (eIOHandlerNone),
    m_session_is_active (false),
    m_pty_slave_is_open (false),
    m_valid_session (true),
    m_command_thread_state (nullptr)
{

    ScriptInterpreterPython::InitializePrivate ();

    m_dictionary_name.append("_dict");
    StreamString run_string;
    run_string.Printf ("%s = dict()", m_dictionary_name.c_str());

    Locker locker(this,
                  ScriptInterpreterPython::Locker::AcquireLock,
                  ScriptInterpreterPython::Locker::FreeAcquiredLock);
    PyRun_SimpleString (run_string.GetData());

    run_string.Clear();

    // Importing 'lldb' module calls SBDebugger::Initialize, which calls Debugger::Initialize, which increments a
    // global debugger ref-count; therefore we need to check the ref-count before and after importing lldb, and if the
    // ref-count increased we need to call Debugger::Terminate here to decrement the ref-count so that when the final 
    // call to Debugger::Terminate is made, the ref-count has the correct value. 
    //
    // Bonus question:  Why doesn't the ref-count always increase?  Because sometimes lldb has already been imported, in
    // which case the code inside it, including the call to SBDebugger::Initialize(), does not get executed.
    
    int old_count = Debugger::TestDebuggerRefCount();
    
    run_string.Printf ("run_one_line (%s, 'import copy, os, re, sys, uuid, lldb')", m_dictionary_name.c_str());
    PyRun_SimpleString (run_string.GetData());

    // WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
    // and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task
    run_string.Clear();
    run_string.Printf ("run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')", m_dictionary_name.c_str());
    PyRun_SimpleString (run_string.GetData());
    run_string.Clear();

    int new_count = Debugger::TestDebuggerRefCount();
    
    if (new_count > old_count)
        Debugger::Terminate();

    run_string.Printf ("run_one_line (%s, 'import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line')", m_dictionary_name.c_str());
    PyRun_SimpleString (run_string.GetData());
    run_string.Clear();
    
    run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64 "; pydoc.pager = pydoc.plainpager')", m_dictionary_name.c_str(),
                       interpreter.GetDebugger().GetID());
    PyRun_SimpleString (run_string.GetData());
}

ScriptInterpreterPython::~ScriptInterpreterPython ()
{
}

void
ScriptInterpreterPython::IOHandlerActivated (IOHandler &io_handler)
{
    const char *instructions = nullptr;
    
    switch (m_active_io_handler)
    {
    case eIOHandlerNone:
            break;
    case eIOHandlerBreakpoint:
            instructions = R"(Enter your Python command(s). Type 'DONE' to end.
def function (frame, bp_loc, internal_dict):
    """frame: the lldb.SBFrame for the location at which you stopped
       bp_loc: an lldb.SBBreakpointLocation for the breakpoint location information
       internal_dict: an LLDB support object not to be used"""
)";
            break;
    case eIOHandlerWatchpoint:
            instructions = "Enter your Python command(s). Type 'DONE' to end.\n";
            break;
    }
    
    if (instructions)
    {
        StreamFileSP output_sp(io_handler.GetOutputStreamFile());
        if (output_sp)
        {
            output_sp->PutCString(instructions);
            output_sp->Flush();
        }
    }
}

void
ScriptInterpreterPython::IOHandlerInputComplete (IOHandler &io_handler, std::string &data)
{
    io_handler.SetIsDone(true);
    bool batch_mode = m_interpreter.GetBatchCommandMode();

    switch (m_active_io_handler)
    {
    case eIOHandlerNone:
        break;
    case eIOHandlerBreakpoint:
        {
            BreakpointOptions *bp_options = (BreakpointOptions *)io_handler.GetUserData();
            std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());
            if (data_ap.get())
            {
                data_ap->user_source.SplitIntoLines(data);
                
                if (GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source).Success())
                {
                    BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
                    bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
                }
                else if (!batch_mode)
                {
                    StreamFileSP error_sp = io_handler.GetErrorStreamFile();
                    if (error_sp)
                    {
                        error_sp->Printf ("Warning: No command attached to breakpoint.\n");
                        error_sp->Flush();
                    }
                }
            }
            m_active_io_handler = eIOHandlerNone;
        }
        break;
    case eIOHandlerWatchpoint:
        {
            WatchpointOptions *wp_options = (WatchpointOptions *)io_handler.GetUserData();
            std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());
            if (data_ap.get())
            {
                data_ap->user_source.SplitIntoLines(data);
                
                if (GenerateWatchpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
                {
                    BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
                    wp_options->SetCallback (ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
                }
                else if (!batch_mode)
                {
                    StreamFileSP error_sp = io_handler.GetErrorStreamFile();
                    if (error_sp)
                    {
                        error_sp->Printf ("Warning: No command attached to breakpoint.\n");
                        error_sp->Flush();
                    }
                }
            }
            m_active_io_handler = eIOHandlerNone;
        }
        break;
    }


}


void
ScriptInterpreterPython::ResetOutputFileHandle (FILE *fh)
{
}

void
ScriptInterpreterPython::SaveTerminalState (int fd)
{
    // Python mucks with the terminal state of STDIN. If we can possibly avoid
    // this by setting the file handles up correctly prior to entering the
    // interpreter we should. For now we save and restore the terminal state
    // on the input file handle.
    m_terminal_state.Save (fd, false);
}

void
ScriptInterpreterPython::RestoreTerminalState ()
{
    // Python mucks with the terminal state of STDIN. If we can possibly avoid
    // this by setting the file handles up correctly prior to entering the
    // interpreter we should. For now we save and restore the terminal state
    // on the input file handle.
    m_terminal_state.Restore();
}

void
ScriptInterpreterPython::LeaveSession ()
{
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
    if (log)
        log->PutCString("ScriptInterpreterPython::LeaveSession()");

    // checking that we have a valid thread state - since we use our own threading and locking
    // in some (rare) cases during cleanup Python may end up believing we have no thread state
    // and PyImport_AddModule will crash if that is the case - since that seems to only happen
    // when destroying the SBDebugger, we can make do without clearing up stdout and stderr

    // rdar://problem/11292882
    // When the current thread state is NULL, PyThreadState_Get() issues a fatal error.
    if (PyThreadState_GetDict())
    {
        PythonDictionary &sys_module_dict = GetSysModuleDictionary ();
        if (sys_module_dict)
        {
            if (m_saved_stdin)
            {
                sys_module_dict.SetItemForKey("stdin", m_saved_stdin);
                m_saved_stdin.Reset ();
            }
            if (m_saved_stdout)
            {
                sys_module_dict.SetItemForKey("stdout", m_saved_stdout);
                m_saved_stdout.Reset ();
            }
            if (m_saved_stderr)
            {
                sys_module_dict.SetItemForKey("stderr", m_saved_stderr);
                m_saved_stderr.Reset ();
            }
        }
    }

    m_session_is_active = false;
}

bool
ScriptInterpreterPython::EnterSession (uint16_t on_entry_flags,
                                       FILE *in,
                                       FILE *out,
                                       FILE *err)
{
    // If we have already entered the session, without having officially 'left' it, then there is no need to 
    // 'enter' it again.
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
    if (m_session_is_active)
    {
        if (log)
            log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ") session is already active, returning without doing anything", on_entry_flags);
        return false;
    }

    if (log)
        log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ")", on_entry_flags);
    

    m_session_is_active = true;

    StreamString run_string;

    if (on_entry_flags & Locker::InitGlobals)
    {
        run_string.Printf (    "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
        run_string.Printf (    "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
        run_string.PutCString ("; lldb.target = lldb.debugger.GetSelectedTarget()");
        run_string.PutCString ("; lldb.process = lldb.target.GetProcess()");
        run_string.PutCString ("; lldb.thread = lldb.process.GetSelectedThread ()");
        run_string.PutCString ("; lldb.frame = lldb.thread.GetSelectedFrame ()");
        run_string.PutCString ("')");
    }
    else
    {
        // If we aren't initing the globals, we should still always set the debugger (since that is always unique.)
        run_string.Printf (    "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
        run_string.Printf (    "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
        run_string.PutCString ("')");
    }

    PyRun_SimpleString (run_string.GetData());
    run_string.Clear();

    PythonDictionary &sys_module_dict = GetSysModuleDictionary ();
    if (sys_module_dict)
    {
        lldb::StreamFileSP in_sp;
        lldb::StreamFileSP out_sp;
        lldb::StreamFileSP err_sp;
        if (in == nullptr || out == nullptr || err == nullptr)
            m_interpreter.GetDebugger().AdoptTopIOHandlerFilesIfInvalid (in_sp, out_sp, err_sp);

        if (in == nullptr && in_sp && (on_entry_flags & Locker::NoSTDIN) == 0)
            in = in_sp->GetFile().GetStream();
        if (in)
        {
            m_saved_stdin.Reset(sys_module_dict.GetItemForKey("stdin"));

            PyObject *new_file = PyFile_FromFile (in, (char *) "", (char *) "r", nullptr);
            sys_module_dict.SetItemForKey ("stdin", new_file);
            Py_DECREF (new_file);
        }
        else
            m_saved_stdin.Reset();
        
        if (out == nullptr && out_sp)
            out = out_sp->GetFile().GetStream();
        if (out)
        {
            m_saved_stdout.Reset(sys_module_dict.GetItemForKey("stdout"));

            PyObject *new_file = PyFile_FromFile (out, (char *) "", (char *) "w", nullptr);
            sys_module_dict.SetItemForKey ("stdout", new_file);
            Py_DECREF (new_file);
        }
        else
            m_saved_stdout.Reset();

        if (err == nullptr && err_sp)
            err = err_sp->GetFile().GetStream();
        if (err)
        {
            m_saved_stderr.Reset(sys_module_dict.GetItemForKey("stderr"));

            PyObject *new_file = PyFile_FromFile (err, (char *) "", (char *) "w", nullptr);
            sys_module_dict.SetItemForKey ("stderr", new_file);
            Py_DECREF (new_file);
        }
        else
            m_saved_stderr.Reset();
    }

    if (PyErr_Occurred())
        PyErr_Clear ();
    
    return true;
}

PythonObject &
ScriptInterpreterPython::GetMainModule ()
{
    if (!m_main_module)
        m_main_module.Reset(PyImport_AddModule ("__main__"));
    return m_main_module;
}

PythonDictionary &
ScriptInterpreterPython::GetSessionDictionary ()
{
    if (!m_session_dict)
    {
        PythonObject &main_module = GetMainModule ();
        if (main_module)
        {
            PythonDictionary main_dict(PyModule_GetDict (main_module.get()));
            if (main_dict)
            {
                m_session_dict = main_dict.GetItemForKey(m_dictionary_name.c_str());
            }
        }
    }
    return m_session_dict;
}

PythonDictionary &
ScriptInterpreterPython::GetSysModuleDictionary ()
{
    if (!m_sys_module_dict)
    {
        PyObject *sys_module = PyImport_AddModule ("sys");
        if (sys_module)
            m_sys_module_dict.Reset(PyModule_GetDict (sys_module));
    }
    return m_sys_module_dict;
}

static std::string
GenerateUniqueName (const char* base_name_wanted,
                    uint32_t& functions_counter,
                    void* name_token = nullptr)
{
    StreamString sstr;
    
    if (!base_name_wanted)
        return std::string();
    
    if (!name_token)
        sstr.Printf ("%s_%d", base_name_wanted, functions_counter++);
    else
        sstr.Printf ("%s_%p", base_name_wanted, name_token);
    
    return sstr.GetString();
}

bool
ScriptInterpreterPython::GetEmbeddedInterpreterModuleObjects ()
{
    if (!m_run_one_line_function)
    {
        PyObject *module = PyImport_AddModule ("lldb.embedded_interpreter");
        if (module != nullptr)
        {
            PythonDictionary module_dict (PyModule_GetDict (module));
            if (module_dict)
            {
                m_run_one_line_function = module_dict.GetItemForKey("run_one_line");
                m_run_one_line_str_global = module_dict.GetItemForKey("g_run_one_line_str");
            }
        }
    }
    return (bool)m_run_one_line_function;
}

static void
ReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
{
    if (src && src_len)
    {
        Stream *strm = (Stream *)baton;
        strm->Write(src, src_len);
        strm->Flush();
    }
}

bool
ScriptInterpreterPython::ExecuteOneLine (const char *command, CommandReturnObject *result, const ExecuteScriptOptions &options)
{
    if (!m_valid_session)
        return false;
    
    if (command && command[0])
    {
        // We want to call run_one_line, passing in the dictionary and the command string.  We cannot do this through
        // PyRun_SimpleString here because the command string may contain escaped characters, and putting it inside
        // another string to pass to PyRun_SimpleString messes up the escaping.  So we use the following more complicated
        // method to pass the command string directly down to Python.
        Debugger &debugger = m_interpreter.GetDebugger();
        
        StreamFileSP input_file_sp;
        StreamFileSP output_file_sp;
        StreamFileSP error_file_sp;
        Communication output_comm ("lldb.ScriptInterpreterPython.ExecuteOneLine.comm");
        int pipe_fds[2] = { -1, -1 };
        
        if (options.GetEnableIO())
        {
            if (result)
            {
                input_file_sp = debugger.GetInputFile();
                // Set output to a temporary file so we can forward the results on to the result object
                
                int err = pipe(pipe_fds);
                if (err == 0)
                {
                    std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor(pipe_fds[0], true));
                    if (conn_ap->IsConnected())
                    {
                        output_comm.SetConnection(conn_ap.release());
                        output_comm.SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived, &result->GetOutputStream());
                        output_comm.StartReadThread();
                        FILE *outfile_handle = fdopen (pipe_fds[1], "w");
                        output_file_sp.reset(new StreamFile(outfile_handle, true));
                        error_file_sp = output_file_sp;
                        if (outfile_handle)
                            ::setbuf (outfile_handle, nullptr);
                        
                        result->SetImmediateOutputFile(debugger.GetOutputFile()->GetFile().GetStream());
                        result->SetImmediateErrorFile(debugger.GetErrorFile()->GetFile().GetStream());
                    }
                }
            }
            if (!input_file_sp || !output_file_sp || !error_file_sp)
                debugger.AdoptTopIOHandlerFilesIfInvalid(input_file_sp, output_file_sp, error_file_sp);
        }
        else
        {
            input_file_sp.reset (new StreamFile ());
            input_file_sp->GetFile().Open("/dev/null", File::eOpenOptionRead);
            output_file_sp.reset (new StreamFile ());
            output_file_sp->GetFile().Open("/dev/null", File::eOpenOptionWrite);
            error_file_sp = output_file_sp;
        }

        FILE *in_file = input_file_sp->GetFile().GetStream();
        FILE *out_file = output_file_sp->GetFile().GetStream();
        FILE *err_file = error_file_sp->GetFile().GetStream();
        Locker locker(this,
                      ScriptInterpreterPython::Locker::AcquireLock |
                      ScriptInterpreterPython::Locker::InitSession |
                      (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
                      ScriptInterpreterPython::Locker::FreeAcquiredLock |
                      ScriptInterpreterPython::Locker::TearDownSession,
                      in_file,
                      out_file,
                      err_file);
        
        bool success = false;
        
        // Find the correct script interpreter dictionary in the main module.
        PythonDictionary &session_dict = GetSessionDictionary ();
        if (session_dict)
        {
            if (GetEmbeddedInterpreterModuleObjects ())
            {
                PyObject *pfunc = m_run_one_line_function.get();
                
                if (pfunc && PyCallable_Check (pfunc))
                {
                    PythonObject pargs (Py_BuildValue("(Os)", session_dict.get(), command));
                    if (pargs)
                    {
                        PythonObject return_value(PyObject_CallObject (pfunc, pargs.get()));
                        if (return_value)
                            success = true;
                        else if (options.GetMaskoutErrors() && PyErr_Occurred ())
                        {
                            PyErr_Print();
                            PyErr_Clear();
                        }
                    }
                }
            }
        }

        // Flush our output and error file handles
        ::fflush (out_file);
        if (out_file != err_file)
            ::fflush (err_file);
        
        if (pipe_fds[0] != -1)
        {
            // Close the write end of the pipe since we are done with our
            // one line script. This should cause the read thread that
            // output_comm is using to exit
            output_file_sp->GetFile().Close();
            // The close above should cause this thread to exit when it gets
            // to the end of file, so let it get all its data
            output_comm.JoinReadThread();
            // Now we can close the read end of the pipe
            output_comm.Disconnect();
        }
        
        
        if (success)
            return true;

        // The one-liner failed.  Append the error message.
        if (result)
            result->AppendErrorWithFormat ("python failed attempting to evaluate '%s'\n", command);
        return false;
    }

    if (result)
        result->AppendError ("empty command passed to python\n");
    return false;
}


class IOHandlerPythonInterpreter :
    public IOHandler
{
public:
    
    IOHandlerPythonInterpreter (Debugger &debugger,
                                ScriptInterpreterPython *python) :
        IOHandler (debugger),
        m_python(python)
    {
        
    }
    
    virtual
    ~IOHandlerPythonInterpreter()
    {
        
    }
    
    virtual ConstString
    GetControlSequence (char ch)
    {
        if (ch == 'd')
            return ConstString("quit()\n");
        return ConstString();
    }

    virtual void
    Run ()
    {
        if (m_python)
        {
            int stdin_fd = GetInputFD();
            if (stdin_fd >= 0)
            {
                Terminal terminal(stdin_fd);
                TerminalState terminal_state;
                const bool is_a_tty = terminal.IsATerminal();
                
                if (is_a_tty)
                {
                    terminal_state.Save (stdin_fd, false);
                    terminal.SetCanonical(false);
                    terminal.SetEcho(true);
                }
                
                ScriptInterpreterPython::Locker locker (m_python,
                                                        ScriptInterpreterPython::Locker::AcquireLock |
                                                        ScriptInterpreterPython::Locker::InitSession |
                                                        ScriptInterpreterPython::Locker::InitGlobals,
                                                        ScriptInterpreterPython::Locker::FreeAcquiredLock |
                                                        ScriptInterpreterPython::Locker::TearDownSession);

                // The following call drops into the embedded interpreter loop and stays there until the
                // user chooses to exit from the Python interpreter.
                // This embedded interpreter will, as any Python code that performs I/O, unlock the GIL before
                // a system call that can hang, and lock it when the syscall has returned.
                
                // We need to surround the call to the embedded interpreter with calls to PyGILState_Ensure and
                // PyGILState_Release (using the Locker above). This is because Python has a global lock which must be held whenever we want
                // to touch any Python objects. Otherwise, if the user calls Python code, the interpreter state will be off,
                // and things could hang (it's happened before).
                
                StreamString run_string;
                run_string.Printf ("run_python_interpreter (%s)", m_python->GetDictionaryName ());
                PyRun_SimpleString (run_string.GetData());
                
                if (is_a_tty)
                    terminal_state.Restore();
            }
        }
        SetIsDone(true);
    }

    virtual void
    Hide ()
    {
        
    }
    
    virtual void
    Refresh ()
    {
        
    }

    virtual void
    Cancel ()
    {
        
    }

    virtual bool
    Interrupt ()
    {
        Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));

        PyThreadState* state = _PyThreadState_Current;
        if (!state)
            state = m_python->GetThreadState();
        if (state)
        {
            long tid = state->thread_id;
            _PyThreadState_Current = state;
            int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
            if (log)
                log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p",
                            tid,num_threads,state);
        }
        else if (log)
            log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL");

        return false;
    }
    
    virtual void
    GotEOF()
    {
        
    }
protected:
    ScriptInterpreterPython *m_python;
};


void
ScriptInterpreterPython::ExecuteInterpreterLoop ()
{
    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

    Debugger &debugger = GetCommandInterpreter().GetDebugger();

    // At the moment, the only time the debugger does not have an input file handle is when this is called
    // directly from Python, in which case it is both dangerous and unnecessary (not to mention confusing) to
    // try to embed a running interpreter loop inside the already running Python interpreter loop, so we won't
    // do it.

    if (!debugger.GetInputFile()->GetFile().IsValid())
        return;

    IOHandlerSP io_handler_sp (new IOHandlerPythonInterpreter (debugger, this));
    if (io_handler_sp)
    {
        debugger.PushIOHandler(io_handler_sp);
    }
}

bool
ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string,
                                                   ScriptInterpreter::ScriptReturnType return_type,
                                                   void *ret_value,
                                                   const ExecuteScriptOptions &options)
{

    Locker locker(this,
                  ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
                  ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);

    PyObject *py_return = nullptr;
    PythonObject &main_module = GetMainModule ();
    PythonDictionary globals (PyModule_GetDict(main_module.get()));
    PyObject *py_error = nullptr;
    bool ret_success = false;
    int success;
    
    PythonDictionary locals = GetSessionDictionary ();
    
    if (!locals)
    {
        locals = PyObject_GetAttrString (globals.get(), m_dictionary_name.c_str());
    }
        
    if (!locals)
        locals = globals;

    py_error = PyErr_Occurred();
    if (py_error != nullptr)
        PyErr_Clear();
    
    if (in_string != nullptr)
    {
        { // scope for PythonInputReaderManager
            //PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
            py_return = PyRun_String (in_string, Py_eval_input, globals.get(), locals.get());
            if (py_return == nullptr)
            { 
                py_error = PyErr_Occurred ();
                if (py_error != nullptr)
                    PyErr_Clear ();

                py_return = PyRun_String (in_string, Py_single_input, globals.get(), locals.get());
            }
        }

        if (py_return != nullptr)
        {
            switch (return_type)
            {
                case eScriptReturnTypeCharPtr: // "char *"
                {
                    const char format[3] = "s#";
                    success = PyArg_Parse (py_return, format, (char **) ret_value);
                    break;
                }
                case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return == Py_None
                {
                    const char format[3] = "z";
                    success = PyArg_Parse (py_return, format, (char **) ret_value);
                    break;
                }
                case eScriptReturnTypeBool:
                {
                    const char format[2] = "b";
                    success = PyArg_Parse (py_return, format, (bool *) ret_value);
                    break;
                }
                case eScriptReturnTypeShortInt:
                {
                    const char format[2] = "h";
                    success = PyArg_Parse (py_return, format, (short *) ret_value);
                    break;
                }
                case eScriptReturnTypeShortIntUnsigned:
                {
                    const char format[2] = "H";
                    success = PyArg_Parse (py_return, format, (unsigned short *) ret_value);
                    break;
                }
                case eScriptReturnTypeInt:
                {
                    const char format[2] = "i";
                    success = PyArg_Parse (py_return, format, (int *) ret_value);
                    break;
                }
                case eScriptReturnTypeIntUnsigned:
                {
                    const char format[2] = "I";
                    success = PyArg_Parse (py_return, format, (unsigned int *) ret_value);
                    break;
                }
                case eScriptReturnTypeLongInt:
                {
                    const char format[2] = "l";
                    success = PyArg_Parse (py_return, format, (long *) ret_value);
                    break;
                }
                case eScriptReturnTypeLongIntUnsigned:
                {
                    const char format[2] = "k";
                    success = PyArg_Parse (py_return, format, (unsigned long *) ret_value);
                    break;
                }
                case eScriptReturnTypeLongLong:
                {
                    const char format[2] = "L";
                    success = PyArg_Parse (py_return, format, (long long *) ret_value);
                    break;
                }
                case eScriptReturnTypeLongLongUnsigned:
                {
                    const char format[2] = "K";
                    success = PyArg_Parse (py_return, format, (unsigned long long *) ret_value);
                    break;
                }
                case eScriptReturnTypeFloat:
                {
                    const char format[2] = "f";
                    success = PyArg_Parse (py_return, format, (float *) ret_value);
                    break;
                }
                case eScriptReturnTypeDouble:
                {
                    const char format[2] = "d";
                    success = PyArg_Parse (py_return, format, (double *) ret_value);
                    break;
                }
                case eScriptReturnTypeChar:
                {
                    const char format[2] = "c";
                    success = PyArg_Parse (py_return, format, (char *) ret_value);
                    break;
                }
                case eScriptReturnTypeOpaqueObject:
                {
                    success = true;
                    Py_XINCREF(py_return);
                    *((PyObject**)ret_value) = py_return;
                    break;
                }
            }
            Py_XDECREF (py_return);
            if (success)
                ret_success = true;
            else
                ret_success = false;
        }
    }

    py_error = PyErr_Occurred();
    if (py_error != nullptr)
    {
        ret_success = false;
        if (options.GetMaskoutErrors())
        {
            if (PyErr_GivenExceptionMatches (py_error, PyExc_SyntaxError))
                PyErr_Print ();
            PyErr_Clear();
        }
    }

    return ret_success;
}

Error
ScriptInterpreterPython::ExecuteMultipleLines (const char *in_string, const ExecuteScriptOptions &options)
{
    Error error;
    
    Locker locker(this,
                  ScriptInterpreterPython::Locker::AcquireLock      | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
                  ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);

    bool success = false;
    PythonObject return_value;
    PythonObject &main_module = GetMainModule ();
    PythonDictionary globals (PyModule_GetDict(main_module.get()));
    PyObject *py_error = nullptr;

    PythonDictionary locals = GetSessionDictionary ();
    
    if (!locals)
    {
        locals = PyObject_GetAttrString (globals.get(), m_dictionary_name.c_str());
    }

    if (!locals)
    {
        locals = globals;
    }

    py_error = PyErr_Occurred();
    if (py_error != nullptr)
        PyErr_Clear();
    
    if (in_string != nullptr)
    {
        struct _node *compiled_node = PyParser_SimpleParseString (in_string, Py_file_input);
        if (compiled_node)
        {
            PyCodeObject *compiled_code = PyNode_Compile (compiled_node, "temp.py");
            if (compiled_code)
            {
                { // scope for PythonInputReaderManager
                    //PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
                    return_value.Reset(PyEval_EvalCode (compiled_code, globals.get(), locals.get()));
                }
                if (return_value)
                    success = true;
            }
        }
    }

    py_error = PyErr_Occurred ();
    if (py_error != nullptr)
    {
//        puts(in_string);
//        _PyObject_Dump (py_error);
//        PyErr_Print();
//        success = false;
        
        PyObject *type = nullptr;
        PyObject *value = nullptr;
        PyObject *traceback = nullptr;
        PyErr_Fetch (&type,&value,&traceback);
        
        // get the backtrace
        std::string bt = ReadPythonBacktrace(traceback);
        
        if (value && value != Py_None)
            error.SetErrorStringWithFormat("%s\n%s", PyString_AsString(PyObject_Str(value)),bt.c_str());
        else
            error.SetErrorStringWithFormat("%s",bt.c_str());
        Py_XDECREF(type);
        Py_XDECREF(value);
        Py_XDECREF(traceback);
        if (options.GetMaskoutErrors())
        {
            PyErr_Clear();
        }
    }

    return error;
}


void
ScriptInterpreterPython::CollectDataForBreakpointCommandCallback (BreakpointOptions *bp_options,
                                                                  CommandReturnObject &result)
{
    m_active_io_handler = eIOHandlerBreakpoint;
    m_interpreter.GetPythonCommandsFromIOHandler ("    ", *this, true, bp_options);
}

void
ScriptInterpreterPython::CollectDataForWatchpointCommandCallback (WatchpointOptions *wp_options,
                                                                  CommandReturnObject &result)
{
    m_active_io_handler = eIOHandlerWatchpoint;
    m_interpreter.GetPythonCommandsFromIOHandler ("    ", *this, true, wp_options);
}

void
ScriptInterpreterPython::SetBreakpointCommandCallbackFunction (BreakpointOptions *bp_options,
                                                               const char *function_name)
{
    // For now just cons up a oneliner that calls the provided function.
    std::string oneliner("return ");
    oneliner += function_name;
    oneliner += "(frame, bp_loc, internal_dict)";
    m_interpreter.GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
                                                                        oneliner.c_str());
}

// Set a Python one-liner as the callback for the breakpoint.
Error
ScriptInterpreterPython::SetBreakpointCommandCallback (BreakpointOptions *bp_options,
                                                       const char *command_body_text)
{
    std::unique_ptr<BreakpointOptions::CommandData> data_ap(new BreakpointOptions::CommandData());

    // Split the command_body_text into lines, and pass that to GenerateBreakpointCommandCallbackData.  That will
    // wrap the body in an auto-generated function, and return the function name in script_source.  That is what
    // the callback will actually invoke.
    
    data_ap->user_source.SplitIntoLines(command_body_text);
    Error error = GenerateBreakpointCommandCallbackData (data_ap->user_source, data_ap->script_source);
    if (error.Success())
    {
        BatonSP baton_sp (new BreakpointOptions::CommandBaton (data_ap.release()));
        bp_options->SetCallback (ScriptInterpreterPython::BreakpointCallbackFunction, baton_sp);
        return error;
    }
    else
        return error;
}

// Set a Python one-liner as the callback for the watchpoint.
void
ScriptInterpreterPython::SetWatchpointCommandCallback (WatchpointOptions *wp_options,
                                                       const char *oneliner)
{
    std::unique_ptr<WatchpointOptions::CommandData> data_ap(new WatchpointOptions::CommandData());

    // It's necessary to set both user_source and script_source to the oneliner.
    // The former is used to generate callback description (as in watchpoint command list)
    // while the latter is used for Python to interpret during the actual callback.

    data_ap->user_source.AppendString (oneliner);
    data_ap->script_source.assign (oneliner);

    if (GenerateWatchpointCommandCallbackData (data_ap->user_source, data_ap->script_source))
    {
        BatonSP baton_sp (new WatchpointOptions::CommandBaton (data_ap.release()));
        wp_options->SetCallback (ScriptInterpreterPython::WatchpointCallbackFunction, baton_sp);
    }
    
    return;
}

Error
ScriptInterpreterPython::ExportFunctionDefinitionToInterpreter (StringList &function_def)
{
    // Convert StringList to one long, newline delimited, const char *.
    std::string function_def_string(function_def.CopyList());

    Error error = ExecuteMultipleLines (function_def_string.c_str(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false));
    return error;
}

Error
ScriptInterpreterPython::GenerateFunction(const char *signature, const StringList &input)
{
    Error error;
    int num_lines = input.GetSize ();
    if (num_lines == 0)
    {
        error.SetErrorString ("No input data.");
        return error;
    }
    
    if (!signature || *signature == 0)
    {
        error.SetErrorString("No output function name.");
        return error;
    }

    StreamString sstr;
    StringList auto_generated_function;
    auto_generated_function.AppendString (signature);
    auto_generated_function.AppendString ("     global_dict = globals()");   // Grab the global dictionary
    auto_generated_function.AppendString ("     new_keys = internal_dict.keys()");    // Make a list of keys in the session dict
    auto_generated_function.AppendString ("     old_keys = global_dict.keys()"); // Save list of keys in global dict
    auto_generated_function.AppendString ("     global_dict.update (internal_dict)"); // Add the session dictionary to the 
    // global dictionary.
    
    // Wrap everything up inside the function, increasing the indentation.
    
    auto_generated_function.AppendString("     if True:");
    for (int i = 0; i < num_lines; ++i)
    {
        sstr.Clear ();
        sstr.Printf ("       %s", input.GetStringAtIndex (i));
        auto_generated_function.AppendString (sstr.GetData());
    }
    auto_generated_function.AppendString ("     for key in new_keys:");  // Iterate over all the keys from session dict
    auto_generated_function.AppendString ("         internal_dict[key] = global_dict[key]");  // Update session dict values
    auto_generated_function.AppendString ("         if key not in old_keys:");       // If key was not originally in global dict
    auto_generated_function.AppendString ("             del global_dict[key]");      //  ...then remove key/value from global dict
    
    // Verify that the results are valid Python.
    
    error = ExportFunctionDefinitionToInterpreter (auto_generated_function);
    
    return error;
}

bool
ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std::string& output, void* name_token)
{
    static uint32_t num_created_functions = 0;
    user_input.RemoveBlankLines ();
    StreamString sstr;
    
    // Check to see if we have any data; if not, just return.
    if (user_input.GetSize() == 0)
        return false;
    
    // Take what the user wrote, wrap it all up inside one big auto-generated Python function, passing in the
    // ValueObject as parameter to the function.
    
    std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_type_print_func", num_created_functions, name_token));
    sstr.Printf ("def %s (valobj, internal_dict):", auto_generated_function_name.c_str());
    
    if (!GenerateFunction(sstr.GetData(), user_input).Success())
        return false;

    // Store the name of the auto-generated function to be called.
    output.assign(auto_generated_function_name);
    return true;
}

bool
ScriptInterpreterPython::GenerateScriptAliasFunction (StringList &user_input, std::string &output)
{
    static uint32_t num_created_functions = 0;
    user_input.RemoveBlankLines ();
    StreamString sstr;
    
    // Check to see if we have any data; if not, just return.
    if (user_input.GetSize() == 0)
        return false;
    
    std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_cmd_alias_func", num_created_functions));

    sstr.Printf ("def %s (debugger, args, result, internal_dict):", auto_generated_function_name.c_str());
    
    if (!GenerateFunction(sstr.GetData(),user_input).Success())
        return false;
    
    // Store the name of the auto-generated function to be called.
    output.assign(auto_generated_function_name);
    return true;
}


bool
ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::string &output, void* name_token)
{
    static uint32_t num_created_classes = 0;
    user_input.RemoveBlankLines ();
    int num_lines = user_input.GetSize ();
    StreamString sstr;
    
    // Check to see if we have any data; if not, just return.
    if (user_input.GetSize() == 0)
        return false;
    
    // Wrap all user input into a Python class
    
    std::string auto_generated_class_name(GenerateUniqueName("lldb_autogen_python_type_synth_class",num_created_classes,name_token));
    
    StringList auto_generated_class;
    
    // Create the function name & definition string.
    
    sstr.Printf ("class %s:", auto_generated_class_name.c_str());
    auto_generated_class.AppendString (sstr.GetData());
        
    // Wrap everything up inside the class, increasing the indentation.
    // we don't need to play any fancy indentation tricks here because there is no
    // surrounding code whose indentation we need to honor
    for (int i = 0; i < num_lines; ++i)
    {
        sstr.Clear ();
        sstr.Printf ("     %s", user_input.GetStringAtIndex (i));
        auto_generated_class.AppendString (sstr.GetData());
    }
    
    
    // Verify that the results are valid Python.
    // (even though the method is ExportFunctionDefinitionToInterpreter, a class will actually be exported)
    // (TODO: rename that method to ExportDefinitionToInterpreter)
    if (!ExportFunctionDefinitionToInterpreter (auto_generated_class).Success())
        return false;
    
    // Store the name of the auto-generated class
    
    output.assign(auto_generated_class_name);
    return true;
}

lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, lldb::ProcessSP process_sp)
{
    if (class_name == nullptr || class_name[0] == '\0')
        return lldb::ScriptInterpreterObjectSP();
    
    if (!process_sp)
        return lldb::ScriptInterpreterObjectSP();
        
    void* ret_val;
    
    {
        Locker py_lock  (this,
                         Locker::AcquireLock | Locker::NoSTDIN,
                         Locker::FreeLock);
        ret_val = g_swig_create_os_plugin    (class_name,
                                              m_dictionary_name.c_str(),
                                              process_sp);
    }
    
    return MakeScriptObject(ret_val);
}

lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
{
    Locker py_lock(this,
                   Locker::AcquireLock | Locker::NoSTDIN,
                   Locker::FreeLock);
    
    static char callee_name[] = "get_register_info";
    
    if (!os_plugin_object_sp)
        return lldb::ScriptInterpreterObjectSP();
    
    PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
    
    if (implementor == nullptr || implementor == Py_None)
        return lldb::ScriptInterpreterObjectSP();
    
    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return lldb::ScriptInterpreterObjectSP();
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return lldb::ScriptInterpreterObjectSP();
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
    
    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }
    
    return MakeScriptObject(py_return);
}

lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
{
    Locker py_lock (this,
                    Locker::AcquireLock | Locker::NoSTDIN,
                    Locker::FreeLock);

    static char callee_name[] = "get_thread_info";
    
    if (!os_plugin_object_sp)
        return lldb::ScriptInterpreterObjectSP();
    
    PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
    
    if (implementor == nullptr || implementor == Py_None)
        return lldb::ScriptInterpreterObjectSP();
    
    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return lldb::ScriptInterpreterObjectSP();
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return lldb::ScriptInterpreterObjectSP();
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
    
    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }
    
    return MakeScriptObject(py_return);
}

// GetPythonValueFormatString provides a system independent type safe way to
// convert a variable's type into a python value format. Python value formats
// are defined in terms of builtin C types and could change from system to
// as the underlying typedef for uint* types, size_t, off_t and other values
// change.

template <typename T>
const char *GetPythonValueFormatString(T t)
{
    assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a specialization of GetPythonValueFormatString() to support this type.");
    return nullptr;
}
template <> const char *GetPythonValueFormatString (char *)             { return "s"; }
template <> const char *GetPythonValueFormatString (char)               { return "b"; }
template <> const char *GetPythonValueFormatString (unsigned char)      { return "B"; }
template <> const char *GetPythonValueFormatString (short)              { return "h"; }
template <> const char *GetPythonValueFormatString (unsigned short)     { return "H"; }
template <> const char *GetPythonValueFormatString (int)                { return "i"; }
template <> const char *GetPythonValueFormatString (unsigned int)       { return "I"; }
template <> const char *GetPythonValueFormatString (long)               { return "l"; }
template <> const char *GetPythonValueFormatString (unsigned long)      { return "k"; }
template <> const char *GetPythonValueFormatString (long long)          { return "L"; }
template <> const char *GetPythonValueFormatString (unsigned long long) { return "K"; }
template <> const char *GetPythonValueFormatString (float t)            { return "f"; }
template <> const char *GetPythonValueFormatString (double t)           { return "d"; }

lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
                                                       lldb::tid_t tid)
{
    Locker py_lock (this,
                    Locker::AcquireLock | Locker::NoSTDIN,
                    Locker::FreeLock);

    static char callee_name[] = "get_register_data";
    static char *param_format = const_cast<char *>(GetPythonValueFormatString(tid));
    
    if (!os_plugin_object_sp)
        return lldb::ScriptInterpreterObjectSP();
    
    PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
    
    if (implementor == nullptr || implementor == Py_None)
        return lldb::ScriptInterpreterObjectSP();

    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return lldb::ScriptInterpreterObjectSP();
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return lldb::ScriptInterpreterObjectSP();
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, tid);

    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }
    
    return MakeScriptObject(py_return);
}

lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
                                                lldb::tid_t tid,
                                                lldb::addr_t context)
{
    Locker py_lock(this,
                   Locker::AcquireLock | Locker::NoSTDIN,
                   Locker::FreeLock);
    
    static char callee_name[] = "create_thread";
    std::string param_format;
    param_format += GetPythonValueFormatString(tid);
    param_format += GetPythonValueFormatString(context);
    
    if (!os_plugin_object_sp)
        return lldb::ScriptInterpreterObjectSP();
    
    PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
    
    if (implementor == nullptr || implementor == Py_None)
        return lldb::ScriptInterpreterObjectSP();
    
    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    if (pmeth == nullptr || pmeth == Py_None)
    {
        Py_XDECREF(pmeth);
        return lldb::ScriptInterpreterObjectSP();
    }
    
    if (PyCallable_Check(pmeth) == 0)
    {
        if (PyErr_Occurred())
        {
            PyErr_Clear();
        }
        
        Py_XDECREF(pmeth);
        return lldb::ScriptInterpreterObjectSP();
    }
    
    if (PyErr_Occurred())
    {
        PyErr_Clear();
    }
    
    Py_XDECREF(pmeth);
    
    // right now we know this function exists and is callable..
    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, &param_format[0], tid, context);
    
    // if it fails, print the error but otherwise go on
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }
    
    return MakeScriptObject(py_return);
}

lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::LoadPluginModule (const FileSpec& file_spec,
                                           lldb_private::Error& error)
{
    if (!file_spec.Exists())
    {
        error.SetErrorString("no such file");
        return lldb::ScriptInterpreterObjectSP();
    }

    ScriptInterpreterObjectSP module_sp;
    
    if (LoadScriptingModule(file_spec.GetPath().c_str(),true,true,error,&module_sp))
        return module_sp;
    
    return lldb::ScriptInterpreterObjectSP();
}

lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::GetDynamicSettings (lldb::ScriptInterpreterObjectSP plugin_module_sp,
                                             Target* target,
                                             const char* setting_name,
                                             lldb_private::Error& error)
{
    if (!plugin_module_sp || !target || !setting_name || !setting_name[0])
        return lldb::ScriptInterpreterObjectSP();
    
    if (!g_swig_plugin_get)
        return lldb::ScriptInterpreterObjectSP();
    
    PyObject *reply_pyobj = nullptr;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        TargetSP target_sp(target->shared_from_this());
        reply_pyobj = (PyObject*)g_swig_plugin_get(plugin_module_sp->GetObject(),setting_name,target_sp);
    }
    
    return MakeScriptObject(reply_pyobj);
}

lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name,
                                                          lldb::ValueObjectSP valobj)
{
    if (class_name == nullptr || class_name[0] == '\0')
        return lldb::ScriptInterpreterObjectSP();
    
    if (!valobj.get())
        return lldb::ScriptInterpreterObjectSP();
    
    ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
    Target *target = exe_ctx.GetTargetPtr();
    
    if (!target)
        return lldb::ScriptInterpreterObjectSP();
    
    Debugger &debugger = target->GetDebugger();
    ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
    ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
    
    if (!script_interpreter)
        return lldb::ScriptInterpreterObjectSP();
    
    void* ret_val;

    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_synthetic_script (class_name,
                                           python_interpreter->m_dictionary_name.c_str(),
                                           valobj);
    }
    
    return MakeScriptObject(ret_val);
}

bool
ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token)
{
    StringList input;
    input.SplitIntoLines(oneliner, strlen(oneliner));
    return GenerateTypeScriptFunction(input, output, name_token);
}

bool
ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token)
{
    StringList input;
    input.SplitIntoLines(oneliner, strlen(oneliner));
    return GenerateTypeSynthClass(input, output, name_token);
}


Error
ScriptInterpreterPython::GenerateBreakpointCommandCallbackData (StringList &user_input, std::string& output)
{
    static uint32_t num_created_functions = 0;
    user_input.RemoveBlankLines ();
    StreamString sstr;
    Error error;
    if (user_input.GetSize() == 0)
    {
        error.SetErrorString("No input data.");
        return error;
    }

    std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_bp_callback_func_",num_created_functions));
    sstr.Printf ("def %s (frame, bp_loc, internal_dict):", auto_generated_function_name.c_str());
    
    error = GenerateFunction(sstr.GetData(), user_input);
    if (!error.Success())
        return error;
    
    // Store the name of the auto-generated function to be called.
    output.assign(auto_generated_function_name);
    return error;
}

bool
ScriptInterpreterPython::GenerateWatchpointCommandCallbackData (StringList &user_input, std::string& output)
{
    static uint32_t num_created_functions = 0;
    user_input.RemoveBlankLines ();
    StreamString sstr;

    if (user_input.GetSize() == 0)
        return false;

    std::string auto_generated_function_name(GenerateUniqueName("lldb_autogen_python_wp_callback_func_",num_created_functions));
    sstr.Printf ("def %s (frame, wp, internal_dict):", auto_generated_function_name.c_str());
    
    if (!GenerateFunction(sstr.GetData(), user_input).Success())
        return false;
    
    // Store the name of the auto-generated function to be called.
    output.assign(auto_generated_function_name);
    return true;
}

bool
ScriptInterpreterPython::GetScriptedSummary (const char *python_function_name,
                                             lldb::ValueObjectSP valobj,
                                             lldb::ScriptInterpreterObjectSP& callee_wrapper_sp,
                                             std::string& retval)
{
    
    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
    
    if (!valobj.get())
    {
        retval.assign("<no object>");
        return false;
    }
        
    void* old_callee = (callee_wrapper_sp ? callee_wrapper_sp->GetObject() : nullptr);
    void* new_callee = old_callee;
    
    bool ret_val;
    if (python_function_name 
        && *python_function_name)
    {
        {
            Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
            {
                Timer scoped_timer ("g_swig_typescript_callback","g_swig_typescript_callback");
                ret_val = g_swig_typescript_callback (python_function_name,
                                                      GetSessionDictionary().get(),
                                                      valobj,
                                                      &new_callee,
                                                      retval);
            }
        }
    }
    else
    {
        retval.assign("<no function name>");
        return false;
    }
    
    if (new_callee && old_callee != new_callee)
        callee_wrapper_sp = MakeScriptObject(new_callee);
    
    return ret_val;
    
}

void
ScriptInterpreterPython::Clear ()
{
    // Release any global variables that might have strong references to
    // LLDB objects when clearing the python script interpreter.
    Locker locker(this,
                  ScriptInterpreterPython::Locker::AcquireLock,
                  ScriptInterpreterPython::Locker::FreeAcquiredLock);
    PyRun_SimpleString("lldb.debugger = None; lldb.target = None; lldb.process = None; lldb.thread = None; lldb.frame = None");
}

bool
ScriptInterpreterPython::BreakpointCallbackFunction 
(
    void *baton,
    StoppointCallbackContext *context,
    user_id_t break_id,
    user_id_t break_loc_id
)
{
    BreakpointOptions::CommandData *bp_option_data = (BreakpointOptions::CommandData *) baton;
    const char *python_function_name = bp_option_data->script_source.c_str();

    if (!context)
        return true;
        
    ExecutionContext exe_ctx (context->exe_ctx_ref);
    Target *target = exe_ctx.GetTargetPtr();
    
    if (!target)
        return true;
        
    Debugger &debugger = target->GetDebugger();
    ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
    ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
    
    if (!script_interpreter)
        return true;
    
    if (python_function_name && python_function_name[0])
    {
        const StackFrameSP stop_frame_sp (exe_ctx.GetFrameSP());
        BreakpointSP breakpoint_sp = target->GetBreakpointByID (break_id);
        if (breakpoint_sp)
        {
            const BreakpointLocationSP bp_loc_sp (breakpoint_sp->FindLocationByID (break_loc_id));

            if (stop_frame_sp && bp_loc_sp)
            {
                bool ret_val = true;
                {
                    Locker py_lock(python_interpreter, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
                    ret_val = g_swig_breakpoint_callback (python_function_name,
                                                          python_interpreter->m_dictionary_name.c_str(),
                                                          stop_frame_sp, 
                                                          bp_loc_sp);
                }
                return ret_val;
            }
        }
    }
    // We currently always true so we stop in case anything goes wrong when
    // trying to call the script function
    return true;
}

bool
ScriptInterpreterPython::WatchpointCallbackFunction 
(
    void *baton,
    StoppointCallbackContext *context,
    user_id_t watch_id
)
{
    WatchpointOptions::CommandData *wp_option_data = (WatchpointOptions::CommandData *) baton;
    const char *python_function_name = wp_option_data->script_source.c_str();

    if (!context)
        return true;
        
    ExecutionContext exe_ctx (context->exe_ctx_ref);
    Target *target = exe_ctx.GetTargetPtr();
    
    if (!target)
        return true;
        
    Debugger &debugger = target->GetDebugger();
    ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
    ScriptInterpreterPython *python_interpreter = (ScriptInterpreterPython *) script_interpreter;
    
    if (!script_interpreter)
        return true;
    
    if (python_function_name && python_function_name[0])
    {
        const StackFrameSP stop_frame_sp (exe_ctx.GetFrameSP());
        WatchpointSP wp_sp = target->GetWatchpointList().FindByID (watch_id);
        if (wp_sp)
        {
            if (stop_frame_sp && wp_sp)
            {
                bool ret_val = true;
                {
                    Locker py_lock(python_interpreter, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
                    ret_val = g_swig_watchpoint_callback (python_function_name,
                                                          python_interpreter->m_dictionary_name.c_str(),
                                                          stop_frame_sp, 
                                                          wp_sp);
                }
                return ret_val;
            }
        }
    }
    // We currently always true so we stop in case anything goes wrong when
    // trying to call the script function
    return true;
}

size_t
ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor_sp)
{
    if (!implementor_sp)
        return 0;
    
    void* implementor = implementor_sp->GetObject();
    
    if (!implementor)
        return 0;
    
    if (!g_swig_calc_children)
        return 0;

    uint32_t ret_val = 0;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_calc_children (implementor);
    }
    
    return ret_val;
}

lldb::ValueObjectSP
ScriptInterpreterPython::GetChildAtIndex (const lldb::ScriptInterpreterObjectSP& implementor_sp, uint32_t idx)
{
    if (!implementor_sp)
        return lldb::ValueObjectSP();
    
    void* implementor = implementor_sp->GetObject();
    
    if (!implementor)
        return lldb::ValueObjectSP();
    
    if (!g_swig_get_child_index || !g_swig_cast_to_sbvalue)
        return lldb::ValueObjectSP();
    
    lldb::ValueObjectSP ret_val;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        void* child_ptr = g_swig_get_child_index (implementor,idx);
        if (child_ptr != nullptr && child_ptr != Py_None)
        {
            lldb::SBValue* sb_value_ptr = (lldb::SBValue*)g_swig_cast_to_sbvalue(child_ptr);
            if (sb_value_ptr == nullptr)
                Py_XDECREF(child_ptr);
            else
                ret_val = g_swig_get_valobj_sp_from_sbvalue (sb_value_ptr);
        }
        else
        {
            Py_XDECREF(child_ptr);
        }
    }
    
    return ret_val;
}

int
ScriptInterpreterPython::GetIndexOfChildWithName (const lldb::ScriptInterpreterObjectSP& implementor_sp, const char* child_name)
{
    if (!implementor_sp)
        return UINT32_MAX;
    
    void* implementor = implementor_sp->GetObject();
    
    if (!implementor)
        return UINT32_MAX;
    
    if (!g_swig_get_index_child)
        return UINT32_MAX;
    
    int ret_val = UINT32_MAX;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_get_index_child (implementor, child_name);
    }
    
    return ret_val;
}

bool
ScriptInterpreterPython::UpdateSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp)
{
    bool ret_val = false;
    
    if (!implementor_sp)
        return ret_val;
    
    void* implementor = implementor_sp->GetObject();
    
    if (!implementor)
        return ret_val;
    
    if (!g_swig_update_provider)
        return ret_val;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_update_provider (implementor);
    }
    
    return ret_val;
}

bool
ScriptInterpreterPython::MightHaveChildrenSynthProviderInstance (const lldb::ScriptInterpreterObjectSP& implementor_sp)
{
    bool ret_val = false;
    
    if (!implementor_sp)
        return ret_val;
    
    void* implementor = implementor_sp->GetObject();
    
    if (!implementor)
        return ret_val;
    
    if (!g_swig_mighthavechildren_provider)
        return ret_val;
    
    {
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_mighthavechildren_provider (implementor);
    }
    
    return ret_val;
}

static std::string
ReadPythonBacktrace (PyObject* py_backtrace)
{
    PyObject* traceback_module = nullptr,
    *stringIO_module = nullptr,
    *stringIO_builder = nullptr,
    *stringIO_buffer = nullptr,
    *printTB = nullptr,
    *printTB_args = nullptr,
    *printTB_result = nullptr,
    *stringIO_getvalue = nullptr,
    *printTB_string = nullptr;

    std::string retval("backtrace unavailable");
    
    if (py_backtrace && py_backtrace != Py_None)
    {
        traceback_module = PyImport_ImportModule("traceback");
        stringIO_module = PyImport_ImportModule("StringIO");
        
        if (traceback_module && traceback_module != Py_None && stringIO_module && stringIO_module != Py_None)
        {
            stringIO_builder = PyObject_GetAttrString(stringIO_module, "StringIO");
            if (stringIO_builder && stringIO_builder != Py_None)
            {
                stringIO_buffer = PyObject_CallObject(stringIO_builder, nullptr);
                if (stringIO_buffer && stringIO_buffer != Py_None)
                {
                    printTB = PyObject_GetAttrString(traceback_module, "print_tb");
                    if (printTB && printTB != Py_None)
                    {
                        printTB_args = Py_BuildValue("OOO",py_backtrace,Py_None,stringIO_buffer);
                        printTB_result = PyObject_CallObject(printTB, printTB_args);
                        stringIO_getvalue = PyObject_GetAttrString(stringIO_buffer, "getvalue");
                        if (stringIO_getvalue && stringIO_getvalue != Py_None)
                        {
                            printTB_string = PyObject_CallObject (stringIO_getvalue,nullptr);
                            if (printTB_string && printTB_string != Py_None && PyString_Check(printTB_string))
                                retval.assign(PyString_AsString(printTB_string));
                        }
                    }
                }
            }
        }
    }
    Py_XDECREF(traceback_module);
    Py_XDECREF(stringIO_module);
    Py_XDECREF(stringIO_builder);
    Py_XDECREF(stringIO_buffer);
    Py_XDECREF(printTB);
    Py_XDECREF(printTB_args);
    Py_XDECREF(printTB_result);
    Py_XDECREF(stringIO_getvalue);
    Py_XDECREF(printTB_string);
    return retval;
}

bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 Process* process,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!process)
    {
        error.SetErrorString("no process");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_process)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        ProcessSP process_sp(process->shared_from_this());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_process (impl_function, m_dictionary_name.c_str(), process_sp, output);
        if (!ret_val)
            error.SetErrorString("python script evaluation failed");
    }
    return ret_val;
}

bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 Thread* thread,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!thread)
    {
        error.SetErrorString("no thread");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_thread)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        ThreadSP thread_sp(thread->shared_from_this());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_thread (impl_function, m_dictionary_name.c_str(), thread_sp, output);
        if (!ret_val)
            error.SetErrorString("python script evaluation failed");
    }
    return ret_val;
}

bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 Target* target,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!target)
    {
        error.SetErrorString("no thread");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_target)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        TargetSP target_sp(target->shared_from_this());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_target (impl_function, m_dictionary_name.c_str(), target_sp, output);
        if (!ret_val)
            error.SetErrorString("python script evaluation failed");
    }
    return ret_val;
}

bool
ScriptInterpreterPython::RunScriptFormatKeyword (const char* impl_function,
                                                 StackFrame* frame,
                                                 std::string& output,
                                                 Error& error)
{
    bool ret_val;
    if (!frame)
    {
        error.SetErrorString("no frame");
        return false;
    }
    if (!impl_function || !impl_function[0])
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    if (!g_swig_run_script_keyword_frame)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    {
        StackFrameSP frame_sp(frame->shared_from_this());
        Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
        ret_val = g_swig_run_script_keyword_frame (impl_function, m_dictionary_name.c_str(), frame_sp, output);
        if (!ret_val)
            error.SetErrorString("python script evaluation failed");
    }
    return ret_val;
}

uint64_t replace_all(std::string& str, const std::string& oldStr, const std::string& newStr)
{
    size_t pos = 0;
    uint64_t matches = 0;
    while((pos = str.find(oldStr, pos)) != std::string::npos)
    {
        matches++;
        str.replace(pos, oldStr.length(), newStr);
        pos += newStr.length();
    }
    return matches;
}

bool
ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
                                              bool can_reload,
                                              bool init_session,
                                              lldb_private::Error& error,
                                              lldb::ScriptInterpreterObjectSP* module_sp)
{
    if (!pathname || !pathname[0])
    {
        error.SetErrorString("invalid pathname");
        return false;
    }
    
    if (!g_swig_call_module_init)
    {
        error.SetErrorString("internal helper function missing");
        return false;
    }
    
    lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();

    {
        FileSpec target_file(pathname, true);
        std::string basename(target_file.GetFilename().GetCString());
        
        StreamString command_stream;

        // Before executing Pyton code, lock the GIL.
        Locker py_lock (this,
                        Locker::AcquireLock      | (init_session ? Locker::InitSession     : 0) | Locker::NoSTDIN,
                        Locker::FreeAcquiredLock | (init_session ? Locker::TearDownSession : 0));
        
        if (target_file.GetFileType() == FileSpec::eFileTypeInvalid ||
            target_file.GetFileType() == FileSpec::eFileTypeUnknown)
        {
            // if not a valid file of any sort, check if it might be a filename still
            // dot can't be used but / and \ can, and if either is found, reject
            if (strchr(pathname,'\\') || strchr(pathname,'/'))
            {
                error.SetErrorString("invalid pathname");
                return false;
            }
            basename = pathname; // not a filename, probably a package of some sort, let it go through
        }
        else if (target_file.GetFileType() == FileSpec::eFileTypeDirectory ||
                 target_file.GetFileType() == FileSpec::eFileTypeRegular ||
                 target_file.GetFileType() == FileSpec::eFileTypeSymbolicLink)
        {
            std::string directory(target_file.GetDirectory().GetCString());
            replace_all(directory,"'","\\'");
            
            // now make sure that Python has "directory" in the search path
            StreamString command_stream;
            command_stream.Printf("if not (sys.path.__contains__('%s')):\n    sys.path.insert(1,'%s');\n\n",
                                  directory.c_str(),
                                  directory.c_str());
            bool syspath_retval = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false)).Success();
            if (!syspath_retval)
            {
                error.SetErrorString("Python sys.path handling failed");
                return false;
            }
            
            // strip .py or .pyc extension
            ConstString extension = target_file.GetFileNameExtension();
            if (extension)
            {
                if (::strcmp(extension.GetCString(), "py") == 0)
                    basename.resize(basename.length()-3);
                else if(::strcmp(extension.GetCString(), "pyc") == 0)
                    basename.resize(basename.length()-4);
            }
        }
        else
        {
            error.SetErrorString("no known way to import this module specification");
            return false;
        }
        
        // check if the module is already import-ed
        command_stream.Clear();
        command_stream.Printf("sys.modules.__contains__('%s')",basename.c_str());
        bool does_contain = false;
        // this call will succeed if the module was ever imported in any Debugger in the lifetime of the process
        // in which this LLDB framework is living
        bool was_imported_globally = (ExecuteOneLineWithReturn(command_stream.GetData(),
                                                               ScriptInterpreterPython::eScriptReturnTypeBool,
                                                               &does_contain,
                                                               ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false)) && does_contain);
        // this call will fail if the module was not imported in this Debugger before
        command_stream.Clear();
        command_stream.Printf("sys.getrefcount(%s)",basename.c_str());
        bool was_imported_locally = !(GetSessionDictionary().GetItemForKey(basename.c_str()).IsNULLOrNone());
        
        bool was_imported = (was_imported_globally || was_imported_locally);
        
        if (was_imported == true && can_reload == false)
        {
            error.SetErrorString("module already imported");
            return false;
        }

        // now actually do the import
        command_stream.Clear();
        
        if (was_imported)
        {
            if (!was_imported_locally)
                command_stream.Printf("import %s ; reload(%s)",basename.c_str(),basename.c_str());
            else
                command_stream.Printf("reload(%s)",basename.c_str());
        }
        else
            command_stream.Printf("import %s",basename.c_str());
        
        error = ExecuteMultipleLines(command_stream.GetData(), ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false).SetSetLLDBGlobals(false));
        if (error.Fail())
            return false;
        
        // if we are here, everything worked
        // call __lldb_init_module(debugger,dict)
        if (!g_swig_call_module_init (basename.c_str(),
                                      m_dictionary_name.c_str(),
                                      debugger_sp))
        {
            error.SetErrorString("calling __lldb_init_module failed");
            return false;
        }
        
        if (module_sp)
        {
            // everything went just great, now set the module object
            command_stream.Clear();
            command_stream.Printf("%s",basename.c_str());
            void* module_pyobj = nullptr;
            if (ExecuteOneLineWithReturn(command_stream.GetData(),ScriptInterpreter::eScriptReturnTypeOpaqueObject,&module_pyobj) && module_pyobj)
                *module_sp = MakeScriptObject(module_pyobj);
        }
        
        return true;
    }
}

lldb::ScriptInterpreterObjectSP
ScriptInterpreterPython::MakeScriptObject (void* object)
{
    return lldb::ScriptInterpreterObjectSP(new ScriptInterpreterPythonObject(object));
}

ScriptInterpreterPython::SynchronicityHandler::SynchronicityHandler (lldb::DebuggerSP debugger_sp,
                                                                     ScriptedCommandSynchronicity synchro) :
    m_debugger_sp(debugger_sp),
    m_synch_wanted(synchro),
    m_old_asynch(debugger_sp->GetAsyncExecution())
{
    if (m_synch_wanted == eScriptedCommandSynchronicitySynchronous)
        m_debugger_sp->SetAsyncExecution(false);
    else if (m_synch_wanted == eScriptedCommandSynchronicityAsynchronous)
        m_debugger_sp->SetAsyncExecution(true);
}

ScriptInterpreterPython::SynchronicityHandler::~SynchronicityHandler()
{
    if (m_synch_wanted != eScriptedCommandSynchronicityCurrentValue)
        m_debugger_sp->SetAsyncExecution(m_old_asynch);
}

bool
ScriptInterpreterPython::RunScriptBasedCommand(const char* impl_function,
                                               const char* args,
                                               ScriptedCommandSynchronicity synchronicity,
                                               lldb_private::CommandReturnObject& cmd_retobj,
                                               Error& error)
{
    if (!impl_function)
    {
        error.SetErrorString("no function to execute");
        return false;
    }
    
    if (!g_swig_call_command)
    {
        error.SetErrorString("no helper function to run scripted commands");
        return false;
    }
    
    lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this();
    
    if (!debugger_sp.get())
    {
        error.SetErrorString("invalid Debugger pointer");
        return false;
    }
    
    bool ret_val = false;
    
    std::string err_msg;
    
    {
        Locker py_lock(this,
                       Locker::AcquireLock | Locker::InitSession,
                       Locker::FreeLock    | Locker::TearDownSession);
        
        SynchronicityHandler synch_handler(debugger_sp,
                                           synchronicity);
        
        ret_val = g_swig_call_command       (impl_function,
                                             m_dictionary_name.c_str(),
                                             debugger_sp,
                                             args,
                                             cmd_retobj);
    }
    
    if (!ret_val)
        error.SetErrorString("unable to execute script function");
    else
        error.Clear();
    
    return ret_val;
}

// in Python, a special attribute __doc__ contains the docstring
// for an object (function, method, class, ...) if any is defined
// Otherwise, the attribute's value is None
bool
ScriptInterpreterPython::GetDocumentationForItem(const char* item, std::string& dest)
{
	dest.clear();
	if (!item || !*item)
		return false;
    std::string command(item);
    command += ".__doc__";
    
    char* result_ptr = nullptr; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
    
    if (ExecuteOneLineWithReturn (command.c_str(),
                                  ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
                                  &result_ptr,
                                  ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false)))
    {
        if (result_ptr)
            dest.assign(result_ptr);
        return true;
    }
    else
    {
        StreamString str_stream;
        str_stream.Printf("Function %s was not found. Containing module might be missing.",item);
        dest.assign(str_stream.GetData());
        return false;
    }
}

std::unique_ptr<ScriptInterpreterLocker>
ScriptInterpreterPython::AcquireInterpreterLock ()
{
    std::unique_ptr<ScriptInterpreterLocker> py_lock(new Locker(this,
                                                                Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN,
                                                                Locker::FreeLock | Locker::TearDownSession));
    return py_lock;
}

void
ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback swig_init_callback,
                                                SWIGBreakpointCallbackFunction swig_breakpoint_callback,
                                                SWIGWatchpointCallbackFunction swig_watchpoint_callback,
                                                SWIGPythonTypeScriptCallbackFunction swig_typescript_callback,
                                                SWIGPythonCreateSyntheticProvider swig_synthetic_script,
                                                SWIGPythonCalculateNumChildren swig_calc_children,
                                                SWIGPythonGetChildAtIndex swig_get_child_index,
                                                SWIGPythonGetIndexOfChildWithName swig_get_index_child,
                                                SWIGPythonCastPyObjectToSBValue swig_cast_to_sbvalue ,
                                                SWIGPythonGetValueObjectSPFromSBValue swig_get_valobj_sp_from_sbvalue,
                                                SWIGPythonUpdateSynthProviderInstance swig_update_provider,
                                                SWIGPythonMightHaveChildrenSynthProviderInstance swig_mighthavechildren_provider,
                                                SWIGPythonCallCommand swig_call_command,
                                                SWIGPythonCallModuleInit swig_call_module_init,
                                                SWIGPythonCreateOSPlugin swig_create_os_plugin,
                                                SWIGPythonScriptKeyword_Process swig_run_script_keyword_process,
                                                SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread,
                                                SWIGPythonScriptKeyword_Target swig_run_script_keyword_target,
                                                SWIGPythonScriptKeyword_Frame swig_run_script_keyword_frame,
                                                SWIGPython_GetDynamicSetting swig_plugin_get)
{
    g_swig_init_callback = swig_init_callback;
    g_swig_breakpoint_callback = swig_breakpoint_callback;
    g_swig_watchpoint_callback = swig_watchpoint_callback;
    g_swig_typescript_callback = swig_typescript_callback;
    g_swig_synthetic_script = swig_synthetic_script;
    g_swig_calc_children = swig_calc_children;
    g_swig_get_child_index = swig_get_child_index;
    g_swig_get_index_child = swig_get_index_child;
    g_swig_cast_to_sbvalue = swig_cast_to_sbvalue;
    g_swig_get_valobj_sp_from_sbvalue = swig_get_valobj_sp_from_sbvalue;
    g_swig_update_provider = swig_update_provider;
    g_swig_mighthavechildren_provider = swig_mighthavechildren_provider;
    g_swig_call_command = swig_call_command;
    g_swig_call_module_init = swig_call_module_init;
    g_swig_create_os_plugin = swig_create_os_plugin;
    g_swig_run_script_keyword_process = swig_run_script_keyword_process;
    g_swig_run_script_keyword_thread = swig_run_script_keyword_thread;
    g_swig_run_script_keyword_target = swig_run_script_keyword_target;
    g_swig_run_script_keyword_frame = swig_run_script_keyword_frame;
    g_swig_plugin_get = swig_plugin_get;
}

void
ScriptInterpreterPython::InitializePrivate ()
{
    static int g_initialized = false;
    
    if (g_initialized)
        return;
    
    g_initialized = true;

    Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);

    // Python will muck with STDIN terminal state, so save off any current TTY
    // settings so we can restore them.
    TerminalState stdin_tty_state;
    stdin_tty_state.Save(STDIN_FILENO, false);

    PyGILState_STATE gstate;
    Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
    bool threads_already_initialized = false;
    if (PyEval_ThreadsInitialized ()) {
        gstate = PyGILState_Ensure ();
        if (log)
            log->Printf("Ensured PyGILState. Previous state = %slocked\n", gstate == PyGILState_UNLOCKED ? "un" : "");
        threads_already_initialized = true;
    } else {
        // InitThreads acquires the GIL if it hasn't been called before.
        PyEval_InitThreads ();
    }
    Py_InitializeEx (0);

    // Initialize SWIG after setting up python
    if (g_swig_init_callback)
        g_swig_init_callback ();

    // Update the path python uses to search for modules to include the current directory.

    PyRun_SimpleString ("import sys");
    PyRun_SimpleString ("sys.path.append ('.')");

    // Find the module that owns this code and use that path we get to
    // set the sys.path appropriately.

    FileSpec file_spec;
    char python_dir_path[PATH_MAX];
    if (Host::GetLLDBPath (ePathTypePythonDir, file_spec))
    {
        std::string python_path("sys.path.insert(0,\"");
        size_t orig_len = python_path.length();
        if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
        {
            python_path.append (python_dir_path);
            python_path.append ("\")");
            PyRun_SimpleString (python_path.c_str());
            python_path.resize (orig_len);
        }
        
        if (Host::GetLLDBPath (ePathTypeLLDBShlibDir, file_spec))
        {
            if (file_spec.GetPath(python_dir_path, sizeof (python_dir_path)))
            {
                python_path.append (python_dir_path);
                python_path.append ("\")");
                PyRun_SimpleString (python_path.c_str());
                python_path.resize (orig_len);
            }
        }
    }

    PyRun_SimpleString ("sys.dont_write_bytecode = 1; import lldb.embedded_interpreter; from lldb.embedded_interpreter import run_python_interpreter; from lldb.embedded_interpreter import run_one_line; from termios import *");

    if (threads_already_initialized) {
        if (log)
            log->Printf("Releasing PyGILState. Returning to state = %slocked\n", gstate == PyGILState_UNLOCKED ? "un" : "");
        PyGILState_Release (gstate);
    } else {
        // We initialized the threads in this function, just unlock the GIL.
        PyEval_SaveThread();
    }

    stdin_tty_state.Restore();
}

//void
//ScriptInterpreterPython::Terminate ()
//{
//    // We are intentionally NOT calling Py_Finalize here (this would be the logical place to call it).  Calling
//    // Py_Finalize here causes test suite runs to seg fault:  The test suite runs in Python.  It registers 
//    // SBDebugger::Terminate to be called 'at_exit'.  When the test suite Python harness finishes up, it calls 
//    // Py_Finalize, which calls all the 'at_exit' registered functions.  SBDebugger::Terminate calls Debugger::Terminate,
//    // which calls lldb::Terminate, which calls ScriptInterpreter::Terminate, which calls 
//    // ScriptInterpreterPython::Terminate.  So if we call Py_Finalize here, we end up with Py_Finalize being called from
//    // within Py_Finalize, which results in a seg fault.
//    //
//    // Since this function only gets called when lldb is shutting down and going away anyway, the fact that we don't
//    // actually call Py_Finalize should not cause any problems (everything should shut down/go away anyway when the
//    // process exits).
//    //
////    Py_Finalize ();
//}

#endif // #ifdef LLDB_DISABLE_PYTHON
