diff options
author | Bram Moolenaar <Bram@vim.org> | 2010-07-24 23:51:45 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2010-07-24 23:51:45 +0200 |
commit | 170bf1aed576cea59a18c9015a3c7d417053c335 (patch) | |
tree | a3d3ee620442f962634a912372c8fea01048cd50 /src/if_py_both.h | |
parent | 365bdf7a7b2e28624186eed398af542cb9cc3fdb (diff) | |
download | vim-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.h | 256 |
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; +} |