summaryrefslogtreecommitdiff
path: root/src/if_py_both.h
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2010-07-24 23:51:45 +0200
committerBram Moolenaar <Bram@vim.org>2010-07-24 23:51:45 +0200
commit170bf1aed576cea59a18c9015a3c7d417053c335 (patch)
treea3d3ee620442f962634a912372c8fea01048cd50 /src/if_py_both.h
parent365bdf7a7b2e28624186eed398af542cb9cc3fdb (diff)
downloadvim-git-170bf1aed576cea59a18c9015a3c7d417053c335.tar.gz
Move some common code from if_python.c and if_python3.c to if_py_both.h.
Diffstat (limited to 'src/if_py_both.h')
-rw-r--r--src/if_py_both.h256
1 files changed, 256 insertions, 0 deletions
diff --git a/src/if_py_both.h b/src/if_py_both.h
new file mode 100644
index 000000000..8934d95dc
--- /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;
+}