diff src/if_py_both.h @ 4486:8fe768bc1234 v7.3.991

updated for version 7.3.991 Problem: More can be shared by Python 2 and 3. Solution: Move more stuff to if_py_both. (ZyX)
author Bram Moolenaar <bram@vim.org>
date Tue, 21 May 2013 18:19:38 +0200
parents 20e30e31bd86
children 89ea7593fc0c
line wrap: on
line diff
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -30,6 +30,9 @@ typedef int Py_ssize_t;  /* Python 2.4 a
 #define INVALID_WINDOW_VALUE ((win_T *)(-1))
 #define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
 
+typedef void (*rangeinitializer)(void *);
+typedef void (*runner)(const char *, void *, PyGILState_STATE *);
+
 static int ConvertFromPyObject(PyObject *, typval_T *);
 static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
 static PyObject *WindowNew(win_T *, tabpage_T *);
@@ -39,6 +42,8 @@ static PyObject *LineToString(const char
 static PyInt RangeStart;
 static PyInt RangeEnd;
 
+static PyObject *globals;
+
 /*
  * obtain a lock on the Vim data structures
  */
@@ -1296,7 +1301,7 @@ FunctionDestructor(PyObject *self)
     FunctionObject	*this = (FunctionObject *) (self);
 
     func_unref(this->name);
-    PyMem_Del(this->name);
+    PyMem_Free(this->name);
 
     DESTRUCTOR_FINISH(self);
 }
@@ -3432,6 +3437,126 @@ CurrentSetattr(PyObject *self UNUSED, ch
 }
 
     static void
+init_range_cmd(exarg_T *eap)
+{
+    RangeStart = eap->line1;
+    RangeEnd = eap->line2;
+}
+
+    static void
+init_range_eval(typval_T *rettv UNUSED)
+{
+    RangeStart = (PyInt) curwin->w_cursor.lnum;
+    RangeEnd = RangeStart;
+}
+
+    static void
+run_cmd(const char *cmd, void *arg UNUSED, PyGILState_STATE *pygilstate UNUSED)
+{
+    PyRun_SimpleString((char *) cmd);
+}
+
+static const char	*code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
+static int		code_hdr_len = 30;
+
+    static void
+run_do(const char *cmd, void *arg UNUSED, PyGILState_STATE *pygilstate)
+{
+    PyInt	lnum;
+    size_t	len;
+    char	*code;
+    int		status;
+    PyObject	*pyfunc, *pymain;
+
+    if (u_save(RangeStart - 1, RangeEnd + 1) != OK)
+    {
+	EMSG(_("cannot save undo information"));
+	return;
+    }
+
+    len = code_hdr_len + STRLEN(cmd);
+    code = PyMem_New(char, len + 1);
+    memcpy(code, code_hdr, code_hdr_len);
+    STRCPY(code + code_hdr_len, cmd);
+    status = PyRun_SimpleString(code);
+    PyMem_Free(code);
+
+    if (status)
+    {
+	EMSG(_("failed to run the code"));
+	return;
+    }
+
+    status = 0;
+    pymain = PyImport_AddModule("__main__");
+    pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
+    PyGILState_Release(*pygilstate);
+
+    for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
+    {
+	PyObject	*line, *linenr, *ret;
+
+	*pygilstate = PyGILState_Ensure();
+	if (!(line = GetBufferLine(curbuf, lnum)))
+	    goto err;
+	if (!(linenr = PyInt_FromLong((long) lnum)))
+	{
+	    Py_DECREF(line);
+	    goto err;
+	}
+	ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
+	Py_DECREF(line);
+	Py_DECREF(linenr);
+	if (!ret)
+	    goto err;
+
+	if (ret != Py_None)
+	    if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
+		goto err;
+
+	Py_XDECREF(ret);
+	PythonIO_Flush();
+	PyGILState_Release(*pygilstate);
+    }
+    goto out;
+err:
+    *pygilstate = PyGILState_Ensure();
+    PyErr_PrintEx(0);
+    PythonIO_Flush();
+    status = 1;
+out:
+    if (!status)
+	*pygilstate = PyGILState_Ensure();
+    Py_DECREF(pyfunc);
+    PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
+    if (status)
+	return;
+    check_cursor();
+    update_curbuf(NOT_VALID);
+}
+
+    static void
+run_eval(const char *cmd, typval_T *rettv, PyGILState_STATE *pygilstate UNUSED)
+{
+    PyObject	*r;
+
+    r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
+    if (r == NULL)
+    {
+	if (PyErr_Occurred() && !msg_silent)
+	    PyErr_PrintEx(0);
+	EMSG(_("E858: Eval did not return a valid python object"));
+    }
+    else
+    {
+	if (ConvertFromPyObject(r, rettv) == -1)
+	    EMSG(_("E859: Failed to convert returned python object to vim value"));
+	Py_DECREF(r);
+    }
+    PyErr_Clear();
+}
+
+    static void
 set_ref_in_py(const int copyID)
 {
     pylinkedlist_T	*cur;