diff src/if_py_both.h @ 2399:76f0c4918f5c vim73

Move some common code from if_python.c and if_python3.c to if_py_both.h.
author Bram Moolenaar <bram@vim.org>
date Sat, 24 Jul 2010 23:51:45 +0200
parents
children 84d353762845
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/src/if_py_both.h
@@ -0,0 +1,256 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+/*
+ * Python extensions by Paul Moore, David Leonard, Roland Puntaier.
+ *
+ * Common code for if_python.c and if_python3.c.
+ */
+
+/*
+ * obtain a lock on the Vim data structures
+ */
+    static void
+Python_Lock_Vim(void)
+{
+}
+
+/*
+ * release a lock on the Vim data structures
+ */
+    static void
+Python_Release_Vim(void)
+{
+}
+
+/* Output object definition
+ */
+
+static PyObject *OutputWrite(PyObject *, PyObject *);
+static PyObject *OutputWritelines(PyObject *, PyObject *);
+
+typedef void (*writefn)(char_u *);
+static void writer(writefn fn, char_u *str, PyInt n);
+
+typedef struct
+{
+    PyObject_HEAD
+    long softspace;
+    long error;
+} OutputObject;
+
+static struct PyMethodDef OutputMethods[] = {
+    /* name,	    function,		calling,    documentation */
+    {"write",	    OutputWrite,	1,	    "" },
+    {"writelines",  OutputWritelines,	1,	    "" },
+    { NULL,	    NULL,		0,	    NULL }
+};
+
+/*************/
+
+/* Output buffer management
+ */
+
+    static PyObject *
+OutputWrite(PyObject *self, PyObject *args)
+{
+    int len;
+    char *str;
+    int error = ((OutputObject *)(self))->error;
+
+    if (!PyArg_ParseTuple(args, "s#", &str, &len))
+	return NULL;
+
+    Py_BEGIN_ALLOW_THREADS
+    Python_Lock_Vim();
+    writer((writefn)(error ? emsg : msg), (char_u *)str, len);
+    Python_Release_Vim();
+    Py_END_ALLOW_THREADS
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+    static PyObject *
+OutputWritelines(PyObject *self, PyObject *args)
+{
+    PyInt n;
+    PyInt i;
+    PyObject *list;
+    int error = ((OutputObject *)(self))->error;
+
+    if (!PyArg_ParseTuple(args, "O", &list))
+	return NULL;
+    Py_INCREF(list);
+
+    if (!PyList_Check(list)) {
+	PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
+	Py_DECREF(list);
+	return NULL;
+    }
+
+    n = PyList_Size(list);
+
+    for (i = 0; i < n; ++i)
+    {
+	PyObject *line = PyList_GetItem(list, i);
+	char *str;
+	PyInt len;
+
+	if (!PyArg_Parse(line, "s#", &str, &len)) {
+	    PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
+	    Py_DECREF(list);
+	    return NULL;
+	}
+
+	Py_BEGIN_ALLOW_THREADS
+	Python_Lock_Vim();
+	writer((writefn)(error ? emsg : msg), (char_u *)str, len);
+	Python_Release_Vim();
+	Py_END_ALLOW_THREADS
+    }
+
+    Py_DECREF(list);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static char_u *buffer = NULL;
+static PyInt buffer_len = 0;
+static PyInt buffer_size = 0;
+
+static writefn old_fn = NULL;
+
+    static void
+buffer_ensure(PyInt n)
+{
+    PyInt new_size;
+    char_u *new_buffer;
+
+    if (n < buffer_size)
+	return;
+
+    new_size = buffer_size;
+    while (new_size < n)
+	new_size += 80;
+
+    if (new_size != buffer_size)
+    {
+	new_buffer = alloc((unsigned)new_size);
+	if (new_buffer == NULL)
+	    return;
+
+	if (buffer)
+	{
+	    memcpy(new_buffer, buffer, buffer_len);
+	    vim_free(buffer);
+	}
+
+	buffer = new_buffer;
+	buffer_size = new_size;
+    }
+}
+
+    static void
+PythonIO_Flush(void)
+{
+    if (old_fn && buffer_len)
+    {
+	buffer[buffer_len] = 0;
+	old_fn(buffer);
+    }
+
+    buffer_len = 0;
+}
+
+    static void
+writer(writefn fn, char_u *str, PyInt n)
+{
+    char_u *ptr;
+
+    if (fn != old_fn && old_fn != NULL)
+	PythonIO_Flush();
+
+    old_fn = fn;
+
+    while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
+    {
+	PyInt len = ptr - str;
+
+	buffer_ensure(buffer_len + len + 1);
+
+	memcpy(buffer + buffer_len, str, len);
+	buffer_len += len;
+	buffer[buffer_len] = 0;
+	fn(buffer);
+	str = ptr + 1;
+	n -= len + 1;
+	buffer_len = 0;
+    }
+
+    /* Put the remaining text into the buffer for later printing */
+    buffer_ensure(buffer_len + n + 1);
+    memcpy(buffer + buffer_len, str, n);
+    buffer_len += n;
+}
+
+/***************/
+
+static PyTypeObject OutputType;
+
+static OutputObject Output =
+{
+    PyObject_HEAD_INIT(&OutputType)
+    0,
+    0
+};
+
+static OutputObject Error =
+{
+    PyObject_HEAD_INIT(&OutputType)
+    0,
+    1
+};
+
+    static int
+PythonIO_Init_io(void)
+{
+    PySys_SetObject("stdout", (PyObject *)(void *)&Output);
+    PySys_SetObject("stderr", (PyObject *)(void *)&Error);
+
+    if (PyErr_Occurred())
+    {
+	EMSG(_("E264: Python: Error initialising I/O objects"));
+	return -1;
+    }
+
+    return 0;
+}
+
+
+static PyObject *VimError;
+
+/* Check to see whether a Vim error has been reported, or a keyboard
+ * interrupt has been detected.
+ */
+    static int
+VimErrorCheck(void)
+{
+    if (got_int)
+    {
+	PyErr_SetNone(PyExc_KeyboardInterrupt);
+	return 1;
+    }
+    else if (did_emsg && !PyErr_Occurred())
+    {
+	PyErr_SetNone(VimError);
+	return 1;
+    }
+
+    return 0;
+}