%header %{

template <typename T>
PyObject *
SBTypeToSWIGWrapper (T* item);

class PyErr_Cleaner
{
public:
    PyErr_Cleaner(bool print=false) :
    m_print(print)
    {
    }
    
    ~PyErr_Cleaner()
    {
        if (PyErr_Occurred())
        {
            if(m_print && !PyErr_ExceptionMatches(PyExc_SystemExit))
                PyErr_Print();
            PyErr_Clear();
        }
    }
    
private:
    bool m_print;
};

static PyObject*
ResolvePythonName(const char* name,
                  PyObject* pmodule)
{
    if (!name)
        return pmodule;

    PyErr_Cleaner pyerr_cleanup(true);  // show Python errors

    PyObject* main_dict;

    if (!pmodule)
    {
        pmodule = PyImport_AddModule ("__main__");
        if (!pmodule)
            return NULL;
    }

    if (PyType_Check(pmodule))
    {
        main_dict = ((PyTypeObject*)pmodule)->tp_dict;
        if (!main_dict)
            return NULL;
    }
    else if (!PyDict_Check(pmodule))
    {
        main_dict = PyModule_GetDict (pmodule);
        if (!main_dict)
            return NULL;
    }
    else
        main_dict = pmodule;

    const char* dot_pos = ::strchr(name, '.');

    PyObject *dest_object;
    PyObject *key, *value;
    Py_ssize_t pos = 0;

    if (!dot_pos)
    {
        dest_object = NULL;   
        while (PyDict_Next (main_dict, &pos, &key, &value))
        {
            // We have stolen references to the key and value objects in the dictionary; we need to increment 
            // them now so that Python's garbage collector doesn't collect them out from under us.
            Py_INCREF (key);
            Py_INCREF (value);
            if (strcmp (PyString_AsString (key), name) == 0)
            {
                dest_object = value;
                break;
            }
        }        
        if (!dest_object || dest_object == Py_None)
            return NULL;
        return dest_object;
    }
    else
    {
        size_t len = dot_pos - name;
        std::string piece(name,len);
        pmodule = ResolvePythonName(piece.c_str(), main_dict);
        if (!pmodule)
            return NULL;
        return ResolvePythonName(dot_pos+1,pmodule); // tail recursion.. should be optimized by the compiler
    }
}

static PyObject*
FindSessionDictionary(const char *session_dictionary_name)
{
    return ResolvePythonName(session_dictionary_name, NULL);
}

class PyCallable
{
public:
    struct argc {
        size_t num_args;
        bool varargs : 1;
        bool kwargs : 1;
    };

    argc
    GetNumArguments ()
    {
        if (m_callable && PyFunction_Check(m_callable))
        {
            PyCodeObject* code = (PyCodeObject*)PyFunction_GET_CODE(m_callable);
            if (code)
            {
                size_t args = code->co_argcount;
                bool va=false,kw=false;
                if ((code->co_flags & 4) == 4)
                    va = true;
                if ((code->co_flags & 8) == 8)
                    kw = true;
                return {args,va,kw};
            }
        }
        return {SIZE_MAX,false,false};
    }

    operator
    bool ()
    {
        return m_callable != NULL;
    }
    
    template<typename ...Args>
    PyObject*
    operator () (Args... args)
    {
        return (*this)({SBTypeToSWIGWrapper(args)...});
    }
    
    PyObject*
    operator () (std::initializer_list<PyObject*> args)
    {
        PyObject* retval = NULL;
        PyObject* pargs = PyTuple_New (args.size());
        if (pargs == NULL)
        {
            if (PyErr_Occurred())
                PyErr_Clear();
            return retval;
        }
        size_t idx = 0;
        for (auto arg : args)
        {
            if (!arg)
                return retval;
            Py_INCREF(arg); // _SetItem steals a reference
            PyTuple_SetItem(pargs,idx,arg);
            idx++;
        }
        retval = PyObject_CallObject (m_callable, pargs);
        Py_XDECREF (pargs);
        return retval;
    }
    
    static PyCallable
    FindWithPythonObject (PyObject* pfunc)
    {
        return PyCallable(pfunc);
    }
    
    static PyCallable
    FindWithFunctionName (const char *python_function_name,
                          const char *session_dictionary_name)
    {
        if (!python_function_name || !session_dictionary_name)
            return PyCallable();
        if ( (python_function_name[0] == 0) || (session_dictionary_name[0] == 0) )
            return PyCallable();
        return FindWithFunctionName(python_function_name,FindSessionDictionary (session_dictionary_name));
    }
    
    static PyCallable
    FindWithFunctionName (const char *python_function_name,
                          PyObject *session_dict)
    {
        if (!python_function_name || !session_dict)
            return PyCallable();
        if ( (python_function_name[0] == 0))
            return PyCallable();
        return PyCallable(ResolvePythonName (python_function_name, session_dict));
    }
    
    static PyCallable
    FindWithMemberFunction (PyObject *self,
                            const char *python_function_name)
    {
        if (self == NULL || self == Py_None)
            return PyCallable();
        if (!python_function_name || (python_function_name[0] == 0))
            return PyCallable();
        return PyCallable(PyObject_GetAttrString(self, python_function_name));
    }
    
private:
    PyObject* m_callable;
    
    PyCallable (PyObject *callable = NULL) :
    m_callable(callable)
    {
        if (m_callable && PyCallable_Check(m_callable) == false)
            m_callable = NULL;
    }
};

%}

%wrapper %{

// resolve a dotted Python name in the form
// foo.bar.baz.Foobar to an actual Python object
// if pmodule is NULL, the __main__ module will be used
// as the starting point for the search


// This function is called by lldb_private::ScriptInterpreterPython::BreakpointCallbackFunction(...)
// and is used when a script command is attached to a breakpoint for execution.

SWIGEXPORT bool
LLDBSwigPythonBreakpointCallbackFunction 
(
    const char *python_function_name,
    const char *session_dictionary_name,
    const lldb::StackFrameSP& frame_sp, 
    const lldb::BreakpointLocationSP& bp_loc_sp
)
{
    lldb::SBFrame sb_frame (frame_sp);
    lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
    
    bool stop_at_breakpoint = true;
    
    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,session_dictionary_name);
        
        if (!pfunc)
            return stop_at_breakpoint;
        
        PyObject* session_dict = NULL;
        PyObject* pvalue = NULL;
        pvalue = pfunc(sb_frame, sb_bp_loc, session_dict = FindSessionDictionary(session_dictionary_name));
        
        Py_XINCREF (session_dict);
        
        if (pvalue == Py_False)
            stop_at_breakpoint = false;
        
        Py_XDECREF (pvalue);
    }
    
    return stop_at_breakpoint;
}

// This function is called by lldb_private::ScriptInterpreterPython::WatchpointCallbackFunction(...)
// and is used when a script command is attached to a watchpoint for execution.

SWIGEXPORT bool
LLDBSwigPythonWatchpointCallbackFunction 
(
    const char *python_function_name,
    const char *session_dictionary_name,
    const lldb::StackFrameSP& frame_sp, 
    const lldb::WatchpointSP& wp_sp
)
{
    lldb::SBFrame sb_frame (frame_sp);
    lldb::SBWatchpoint sb_wp(wp_sp);

    bool stop_at_watchpoint = true;
    
    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,session_dictionary_name);
        
        if (!pfunc)
            return stop_at_watchpoint;
        
        PyObject* session_dict = NULL;
        PyObject* pvalue = NULL;
        pvalue = pfunc(sb_frame, sb_wp, session_dict = FindSessionDictionary(session_dictionary_name));
        
        Py_XINCREF (session_dict);
        
        if (pvalue == Py_False)
            stop_at_watchpoint = false;
        
        Py_XDECREF (pvalue);
    }
    
    return stop_at_watchpoint;
}

bool
PyObjectToString (PyObject* object,
                  std::string& retval)
{
    retval.clear();
    bool was_ok = false;
    if (object != NULL && object != Py_None)
    {
        if (PyString_Check(object))
        {
            retval.assign(PyString_AsString(object));
            was_ok = true;
        }
        else
        {
            PyObject* value_as_string = PyObject_Str(object);
            if (value_as_string && value_as_string != Py_None && PyString_Check(value_as_string))
            {
                retval.assign(PyString_AsString(value_as_string));
                was_ok = true;
            }
            Py_XDECREF(value_as_string);
        }
    }
    return was_ok;
}

SWIGEXPORT bool
LLDBSwigPythonCallTypeScript 
(
    const char *python_function_name,
    const void *session_dictionary,
    const lldb::ValueObjectSP& valobj_sp,
    void** pyfunct_wrapper,
    std::string& retval
)
{
    lldb::SBValue sb_value (valobj_sp);

    retval.clear();

    if (!python_function_name || !session_dictionary)
        return false;

    PyObject *session_dict = (PyObject*)session_dictionary, *pfunc_impl = NULL, *pvalue = NULL;
    
    if (pyfunct_wrapper && *pyfunct_wrapper && PyFunction_Check (*pyfunct_wrapper))
    {
        pfunc_impl = (PyObject*)(*pyfunct_wrapper);
        if (pfunc_impl->ob_refcnt == 1)
        {
            Py_XDECREF(pfunc_impl);
            pfunc_impl = NULL;
        }
    }

    if (PyDict_Check(session_dict))
    {
        PyErr_Cleaner pyerr_cleanup(true);  // show Python errors
        
        if (!pfunc_impl)
        {
            pfunc_impl = ResolvePythonName (python_function_name, session_dict);
            if (!pfunc_impl || !PyCallable_Check (pfunc_impl))
                return false;
            else
            {
                if (pyfunct_wrapper)
                    *pyfunct_wrapper = pfunc_impl;
            }
        }

        PyCallable pfunc = PyCallable::FindWithPythonObject(pfunc_impl);
        
        if (!pfunc)
            return false;
        
        pvalue = pfunc(sb_value,session_dict);

        Py_INCREF (session_dict);
        
        PyObjectToString(pvalue,retval);
        
        Py_XDECREF (pvalue);
    }
    return true;
}

SWIGEXPORT void*
LLDBSwigPythonCreateSyntheticProvider 
(
    const char *python_class_name,
    const char *session_dictionary_name,
    const lldb::ValueObjectSP& valobj_sp
)
{
    PyObject* retval = NULL;

    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
        Py_RETURN_NONE;

    // I do not want the SBValue to be deallocated when going out of scope because python
    // has ownership of it and will manage memory for this object by itself
    lldb::SBValue *sb_value = new lldb::SBValue(valobj_sp);
    sb_value->SetPreferSyntheticValue(false);
    PyObject *ValObj_PyObj = SBTypeToSWIGWrapper(sb_value);

    if (ValObj_PyObj == NULL)
        Py_RETURN_NONE;
    
    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name,session_dictionary_name);
        
        if (!pfunc)
            return retval;
        
        Py_INCREF(ValObj_PyObj);
        
        PyObject* session_dict = NULL;
        session_dict = FindSessionDictionary(session_dictionary_name);
        retval = pfunc(sb_value, session_dict);
        
        Py_XINCREF (session_dict);
        
        Py_XINCREF(retval);
    }
    
    if (retval)
        return retval;
    else
        Py_RETURN_NONE;
}

SWIGEXPORT void*
LLDBSwigPythonCreateScriptedThreadPlan
(
    const char *python_class_name,
    const char *session_dictionary_name,
    const lldb::ThreadPlanSP& thread_plan_sp
)
{
    PyObject* retval = NULL;

    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
        Py_RETURN_NONE;

    // I do not want the SBThreadPlan to be deallocated when going out of scope because python
    // has ownership of it and will manage memory for this object by itself
    lldb::SBThreadPlan *tp_value = new lldb::SBThreadPlan(thread_plan_sp);

    PyObject *ThreadPlan_PyObj = SBTypeToSWIGWrapper(tp_value);

    if (ThreadPlan_PyObj == NULL)
        Py_RETURN_NONE;
    
    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name, session_dictionary_name);
        
        if (!pfunc)
            return retval;
        
        Py_INCREF(ThreadPlan_PyObj);
        
        PyObject* session_dict = NULL;
        session_dict = FindSessionDictionary(session_dictionary_name);
        retval = pfunc(tp_value, session_dict);

        // FIXME: At this point we should check that the class we found supports all the methods
        // that we need.
        
        Py_XINCREF (session_dict);
        
        Py_XINCREF(retval);
    }

    if (retval)
        return retval;
    else
        Py_RETURN_NONE;
}

SWIGEXPORT bool
LLDBSWIGPythonCallThreadPlan
(
    void *implementor,
    const char *method_name,
    lldb_private::Event *event,
    bool &got_error
)
{
    bool ret_val = false;
    got_error = false;


    PyErr_Cleaner py_err_cleaner(false);
    
    PyCallable pfunc = PyCallable::FindWithMemberFunction((PyObject *) implementor, method_name);
    
    if (!pfunc)
    {
        return ret_val;
    }

    PyObject* py_return = Py_None;

    if (event != NULL)
    {
        lldb::SBEvent sb_event(event);

        PyObject *py_obj_event = SBTypeToSWIGWrapper(sb_event);

        py_return = pfunc(py_obj_event);
    }
    else
    {
        py_return = pfunc();
    }

    if (PyErr_Occurred())
    {
        got_error = true;
        printf ("Return value was neither false nor true for call to %s.\n", method_name);
        PyErr_Print();
    }
    else
    {
        if (py_return == Py_True)
            ret_val = true;
        else if (py_return == Py_False)
            ret_val = false;
        else
        {
            // Somebody returned the wrong thing...
            got_error = true;
            printf ("Wrong return value type for call to %s.\n", method_name);
        }
    }
    
    Py_XDECREF(py_return);

    return ret_val;
}

// wrapper that calls an optional instance member of an object taking no arguments
static PyObject*
LLDBSwigPython_CallOptionalMember
(
    PyObject* self,
    char* callee_name,
    PyObject* ret_if_not_found = Py_None,
    bool* was_found = NULL
)
{
    PyErr_Cleaner py_err_cleaner(false);
    
    PyCallable pfunc = PyCallable::FindWithMemberFunction(self,callee_name);
    
    if (!pfunc)
    {
        if (was_found)
            *was_found = false;
        Py_XINCREF(ret_if_not_found);
        return ret_if_not_found;
    }
    
    if (was_found)
        *was_found = true;
    
    PyObject* py_return = pfunc();
    return py_return;
}

SWIGEXPORT uint32_t
LLDBSwigPython_CalculateNumChildren
(
    PyObject *implementor
)
{
    uint32_t ret_val = UINT32_MAX;

    static char callee_name[] = "num_children";

    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, NULL);

    if (!py_return)
        return ret_val;

    if (PyInt_Check(py_return))
        ret_val = PyInt_AsLong(py_return);

    Py_XDECREF(py_return);
    
    if (PyErr_Occurred())
    {
        PyErr_Print();
        PyErr_Clear();
    }
    
    return ret_val;
}

SWIGEXPORT PyObject*
LLDBSwigPython_GetChildAtIndex
(
    PyObject *implementor,
    uint32_t idx
)
{
    PyErr_Cleaner py_err_cleaner(true);
    
    PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor,"get_child_at_index");
    
    if (!pfunc)
        return NULL;
    
    PyObject *py_return = NULL;
    py_return = pfunc(idx);
    
    if (py_return == NULL || py_return == Py_None)
    {
        Py_XDECREF(py_return);
        return NULL;
    }
    
    lldb::SBValue* sbvalue_ptr = NULL;
    
    if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
    {
        Py_XDECREF(py_return);
        return NULL;
    }
    
    if (sbvalue_ptr == NULL)
        return NULL;
    
    return py_return;    
}

SWIGEXPORT int
LLDBSwigPython_GetIndexOfChildWithName
(
    PyObject *implementor,
    const char* child_name
)
{
    PyErr_Cleaner py_err_cleaner(true);
    
    PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor,"get_child_index");
    
    if (!pfunc)
        return UINT32_MAX;
    
    PyObject *py_return = NULL;
    py_return = pfunc(child_name);
    
    if (py_return == NULL || py_return == Py_None)
    {
        Py_XDECREF(py_return);
        return UINT32_MAX;
    }
    
    long retval = PyInt_AsLong(py_return);
    Py_XDECREF(py_return);

    if (retval >= 0)
        return (uint32_t)retval;
    
    return UINT32_MAX;
}

SWIGEXPORT bool
LLDBSwigPython_UpdateSynthProviderInstance
(
    PyObject *implementor
)
{
    bool ret_val = false;

    static char callee_name[] = "update";

    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name);

    if (py_return == Py_True)
        ret_val = true;

    Py_XDECREF(py_return);
    
    return ret_val;
}

SWIGEXPORT bool
LLDBSwigPython_MightHaveChildrenSynthProviderInstance
(
    PyObject *implementor
)
{
    bool ret_val = false;

    static char callee_name[] = "has_children";

    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_True);

    if (py_return == Py_True)
        ret_val = true;

    Py_XDECREF(py_return);
    
    return ret_val;
}

SWIGEXPORT PyObject*
LLDBSwigPython_GetValueSynthProviderInstance
(
    PyObject *implementor
)
{
    PyObject* ret_val = nullptr;

    static char callee_name[] = "get_value";

    PyObject* py_return = LLDBSwigPython_CallOptionalMember(implementor,callee_name, Py_None);

    if (py_return == Py_None || py_return == nullptr)
        ret_val = nullptr;

    lldb::SBValue* sbvalue_ptr = NULL;
    
    if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1)
        ret_val = nullptr;
    else if (sbvalue_ptr == NULL)
        ret_val = nullptr;
    else
        ret_val = py_return;

    Py_XDECREF(py_return);
    return ret_val;
}

SWIGEXPORT void*
LLDBSWIGPython_CastPyObjectToSBValue
(
    PyObject* data
)
{
    lldb::SBValue* sb_ptr = NULL;
    
    int valid_cast = SWIG_ConvertPtr(data, (void**)&sb_ptr, SWIGTYPE_p_lldb__SBValue, 0);

    if (valid_cast == -1)
        return NULL;

    return sb_ptr;
}

// Currently, SBCommandReturnObjectReleaser wraps a unique pointer to an
// lldb_private::CommandReturnObject. This means that the destructor for the
// SB object will deallocate its contained CommandReturnObject. Because that
// object is used as the real return object for Python-based commands, we want
// it to stay around. Thus, we release the unique pointer before returning from
// LLDBSwigPythonCallCommand, and to guarantee that the release will occur no
// matter how we exit from the function, we have a releaser object whose
// destructor does the right thing for us
class SBCommandReturnObjectReleaser
{
public:
    SBCommandReturnObjectReleaser (lldb::SBCommandReturnObject &obj) :
        m_command_return_object_ref (obj)
    {
    }

    ~SBCommandReturnObjectReleaser ()
    {
        m_command_return_object_ref.Release();
    }
private:
    lldb::SBCommandReturnObject &m_command_return_object_ref;
};

SWIGEXPORT bool
LLDBSwigPythonCallCommand 
(
    const char *python_function_name,
    const char *session_dictionary_name,
    lldb::DebuggerSP& debugger,
    const char* args,
    lldb_private::CommandReturnObject& cmd_retobj,
    lldb::ExecutionContextRefSP exe_ctx_ref_sp
)
{

    lldb::SBCommandReturnObject cmd_retobj_sb(&cmd_retobj);
    SBCommandReturnObjectReleaser cmd_retobj_sb_releaser(cmd_retobj_sb);
    lldb::SBDebugger debugger_sb(debugger);
    lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);

    bool retval = false;

    {
        PyErr_Cleaner py_err_cleaner(true);
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,session_dictionary_name);
        
        if (!pfunc)
            return retval;

        PyObject* session_dict = NULL;
        // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you
        // see comment above for SBCommandReturnObjectReleaser for further details
        PyObject* pvalue = NULL;

        PyCallable::argc argc = pfunc.GetNumArguments();
        if (argc.num_args == 5 || argc.varargs == true)
            pvalue = pfunc(debugger_sb, args, exe_ctx_sb, &cmd_retobj_sb, session_dict = FindSessionDictionary(session_dictionary_name));
        else
            pvalue = pfunc(debugger_sb, args, &cmd_retobj_sb, session_dict = FindSessionDictionary(session_dictionary_name));
        
        Py_XINCREF (session_dict);
        Py_XDECREF (pvalue);
        
        retval = true;
    }
    
    return retval;
}

SWIGEXPORT void*
LLDBSWIGPythonCreateOSPlugin
(
    const char *python_class_name,
    const char *session_dictionary_name,
    const lldb::ProcessSP& process_sp
)
{
    PyObject* retval = NULL;

    if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
        Py_RETURN_NONE;

    // I do not want the SBProcess to be deallocated when going out of scope because python
    // has ownership of it and will manage memory for this object by itself
    lldb::SBProcess *process_sb = new lldb::SBProcess(process_sp);

    PyObject *SBProc_PyObj = SBTypeToSWIGWrapper(process_sb);

    if (SBProc_PyObj == NULL)
        Py_RETURN_NONE;

    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name,session_dictionary_name);
        
        if (!pfunc)
            return retval;
        
        Py_INCREF(SBProc_PyObj);
        
        PyObject* session_dict = NULL;
        session_dict = session_dict = FindSessionDictionary(session_dictionary_name);
        retval = pfunc(SBProc_PyObj);
        
        Py_XINCREF (session_dict);
        
        Py_XINCREF(retval);
    }
    
    if (retval)
        return retval;
    else
        Py_RETURN_NONE;
}

SWIGEXPORT void*
LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb::TargetSP& target_sp)
{

    if (!module || !setting)
        Py_RETURN_NONE;

    lldb::SBTarget target_sb(target_sp);
    
    PyObject *pvalue = NULL;

    {
        PyErr_Cleaner py_err_cleaner(true);
        PyCallable pfunc = PyCallable::FindWithFunctionName("get_dynamic_setting",(PyObject *)module);
        
        if (!pfunc)
            Py_RETURN_NONE;
        
        pvalue = pfunc(target_sb, setting);
    }
    
    return pvalue;
}

SWIGEXPORT bool
LLDBSWIGPythonRunScriptKeywordProcess
(const char* python_function_name,
const char* session_dictionary_name,
lldb::ProcessSP& process,
std::string& output)

{
    bool retval = false;

    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
        return retval;

    lldb::SBProcess process_sb(process);

    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,session_dictionary_name);
        
        if (!pfunc)
            return retval;
        
        PyObject* session_dict = NULL;
        PyObject* pvalue = NULL;
        pvalue = pfunc(process_sb, session_dict = FindSessionDictionary(session_dictionary_name));
        
        Py_XINCREF (session_dict);
        
        if (PyObjectToString(pvalue,output))
            retval = true;
        
        Py_XDECREF(pvalue);
    }
    
    return retval;
}

SWIGEXPORT bool
LLDBSWIGPythonRunScriptKeywordThread
(const char* python_function_name,
const char* session_dictionary_name,
lldb::ThreadSP& thread,
std::string& output)

{
    bool retval = false;

    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
        return retval;

    lldb::SBThread thread_sb(thread);
    
    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,session_dictionary_name);
        
        if (!pfunc)
            return retval;
        
        PyObject* session_dict = NULL;
        PyObject* pvalue = NULL;
        pvalue = pfunc(thread_sb, session_dict = FindSessionDictionary(session_dictionary_name));
        
        Py_XINCREF (session_dict);
        
        if (PyObjectToString(pvalue,output))
            retval = true;
        
        Py_XDECREF(pvalue);
    }
    
    return retval;
}

SWIGEXPORT bool
LLDBSWIGPythonRunScriptKeywordTarget
(const char* python_function_name,
const char* session_dictionary_name,
lldb::TargetSP& target,
std::string& output)

{
    bool retval = false;

    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
        return retval;

    lldb::SBTarget target_sb(target);
    
    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,session_dictionary_name);
        
        if (!pfunc)
            return retval;
        
        PyObject* session_dict = NULL;
        PyObject* pvalue = NULL;
        pvalue = pfunc(target_sb, session_dict = FindSessionDictionary(session_dictionary_name));
        
        Py_XINCREF (session_dict);
        
        if (PyObjectToString(pvalue,output))
            retval = true;
        
        Py_XDECREF(pvalue);
    }
    
    return retval;
}

SWIGEXPORT bool
LLDBSWIGPythonRunScriptKeywordFrame
(const char* python_function_name,
const char* session_dictionary_name,
lldb::StackFrameSP& frame,
std::string& output)

{
    bool retval = false;

    if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
        return retval;

    lldb::SBFrame frame_sb(frame);
    
    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,session_dictionary_name);
        
        if (!pfunc)
            return retval;
        
        PyObject* session_dict = NULL;
        PyObject* pvalue = NULL;
        pvalue = pfunc(frame_sb, session_dict = FindSessionDictionary(session_dictionary_name));
        
        Py_XINCREF (session_dict);
        
        if (PyObjectToString(pvalue,output))
            retval = true;
        
        Py_XDECREF(pvalue);
    }
    
    return retval;
}

SWIGEXPORT bool
LLDBSwigPythonCallModuleInit 
(
    const char *python_module_name,
    const char *session_dictionary_name,
    lldb::DebuggerSP& debugger
)
{
    bool retval = false;

    lldb::SBDebugger debugger_sb(debugger);

    std::string python_function_name_string = python_module_name;
    python_function_name_string += ".__lldb_init_module";
    const char* python_function_name = python_function_name_string.c_str();
    
    {
        PyErr_Cleaner py_err_cleaner(true);
        
        PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,session_dictionary_name);
        
        if (!pfunc)
            return true;
        
        PyObject* session_dict = NULL;
        PyObject* pvalue = NULL;
        pvalue = pfunc(debugger_sb, session_dict = FindSessionDictionary(session_dictionary_name));
        
        Py_XINCREF (session_dict);
        
        retval = true;
        
        Py_XDECREF(pvalue);
    }
    
    return retval;
}
%}


%runtime %{
// Forward declaration to be inserted at the start of LLDBWrapPython.h
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBValue.h"
 
SWIGEXPORT lldb::ValueObjectSP
LLDBSWIGPython_GetValueObjectSPFromSBValue (void* data)
{
    lldb::ValueObjectSP valobj_sp;
    if (data)
    {
        lldb::SBValue* sb_ptr = (lldb::SBValue *)data;
        valobj_sp = sb_ptr->GetSP();
    }
    return valobj_sp;
}

#ifdef __cplusplus
extern "C" {
#endif

void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton);

#ifdef __cplusplus
}
#endif
%}

%wrapper %{


// For the LogOutputCallback functions
void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton) {
    if (baton != Py_None) {
      SWIG_PYTHON_THREAD_BEGIN_BLOCK;
      PyObject_CallFunction(reinterpret_cast<PyObject*>(baton), const_cast<char*>("s"), str);
      SWIG_PYTHON_THREAD_END_BLOCK;
    }
}
%}
