mirror of
https://github.com/vim/vim.git
synced 2025-09-01 21:03:39 -04:00
updated for version 7.3.937
Problem: More can be shared between Python 2 and 3. Solution: Move code to if_py_both.h. (ZyX)
This commit is contained in:
parent
3b9abb6cc2
commit
971db46799
117
src/if_py_both.h
117
src/if_py_both.h
@ -1782,10 +1782,50 @@ CheckWindow(WindowObject *this)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Window object
|
||||
*/
|
||||
|
||||
static int WindowSetattr(PyObject *, char *, PyObject *);
|
||||
static PyObject *WindowRepr(PyObject *);
|
||||
static PyTypeObject WindowType;
|
||||
|
||||
static PyObject *
|
||||
WindowNew(win_T *win)
|
||||
{
|
||||
/* We need to handle deletion of windows underneath us.
|
||||
* If we add a "w_python*_ref" field to the win_T structure,
|
||||
* then we can get at it in win_free() in vim. We then
|
||||
* need to create only ONE Python object per window - if
|
||||
* we try to create a second, just INCREF the existing one
|
||||
* and return it. The (single) Python object referring to
|
||||
* the window is stored in "w_python*_ref".
|
||||
* On a win_free() we set the Python object's win_T* field
|
||||
* to an invalid value. We trap all uses of a window
|
||||
* object, and reject them if the win_T* field is invalid.
|
||||
*
|
||||
* Python2 and Python3 get different fields and different objects:
|
||||
* w_python_ref and w_python3_ref fields respectively.
|
||||
*/
|
||||
|
||||
WindowObject *self;
|
||||
|
||||
if (WIN_PYTHON_REF(win))
|
||||
{
|
||||
self = WIN_PYTHON_REF(win);
|
||||
Py_INCREF(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
self = PyObject_NEW(WindowObject, &WindowType);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
self->win = win;
|
||||
WIN_PYTHON_REF(win) = self;
|
||||
}
|
||||
|
||||
return (PyObject *)(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
WindowAttr(WindowObject *this, char *name)
|
||||
{
|
||||
@ -1809,7 +1849,7 @@ WindowAttr(WindowObject *this, char *name)
|
||||
return OptionsNew(SREQ_WIN, this->win, (checkfun) CheckWindow,
|
||||
(PyObject *) this);
|
||||
else if (strcmp(name,"__members__") == 0)
|
||||
return Py_BuildValue("[sssss]", "buffer", "cursor", "height", "vars",
|
||||
return Py_BuildValue("[ssssss]", "buffer", "cursor", "height", "vars",
|
||||
"options");
|
||||
else
|
||||
return NULL;
|
||||
@ -1821,11 +1861,7 @@ WindowDestructor(PyObject *self)
|
||||
WindowObject *this = (WindowObject *)(self);
|
||||
|
||||
if (this->win && this->win != INVALID_WINDOW_VALUE)
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
this->win->w_python3_ref = NULL;
|
||||
#else
|
||||
this->win->w_python_ref = NULL;
|
||||
#endif
|
||||
WIN_PYTHON_REF(this->win) = NULL;
|
||||
|
||||
DESTRUCTOR_FINISH(self);
|
||||
}
|
||||
@ -2756,15 +2792,50 @@ BufferDestructor(PyObject *self)
|
||||
BufferObject *this = (BufferObject *)(self);
|
||||
|
||||
if (this->buf && this->buf != INVALID_BUFFER_VALUE)
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
this->buf->b_python3_ref = NULL;
|
||||
#else
|
||||
this->buf->b_python_ref = NULL;
|
||||
#endif
|
||||
BUF_PYTHON_REF(this->buf) = NULL;
|
||||
|
||||
DESTRUCTOR_FINISH(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferNew(buf_T *buf)
|
||||
{
|
||||
/* We need to handle deletion of buffers underneath us.
|
||||
* If we add a "b_python*_ref" field to the buf_T structure,
|
||||
* then we can get at it in buf_freeall() in vim. We then
|
||||
* need to create only ONE Python object per buffer - if
|
||||
* we try to create a second, just INCREF the existing one
|
||||
* and return it. The (single) Python object referring to
|
||||
* the buffer is stored in "b_python*_ref".
|
||||
* Question: what to do on a buf_freeall(). We'll probably
|
||||
* have to either delete the Python object (DECREF it to
|
||||
* zero - a bad idea, as it leaves dangling refs!) or
|
||||
* set the buf_T * value to an invalid value (-1?), which
|
||||
* means we need checks in all access functions... Bah.
|
||||
*
|
||||
* Python2 and Python3 get different fields and different objects:
|
||||
* b_python_ref and b_python3_ref fields respectively.
|
||||
*/
|
||||
|
||||
BufferObject *self;
|
||||
|
||||
if (BUF_PYTHON_REF(buf) != NULL)
|
||||
{
|
||||
self = BUF_PYTHON_REF(buf);
|
||||
Py_INCREF(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
self = PyObject_NEW(BufferObject, &BufferType);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
self->buf = buf;
|
||||
BUF_PYTHON_REF(buf) = self;
|
||||
}
|
||||
|
||||
return (PyObject *)(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferAttr(BufferObject *this, char *name)
|
||||
{
|
||||
@ -2783,6 +2854,30 @@ BufferAttr(BufferObject *this, char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyInt
|
||||
BufferLength(PyObject *self)
|
||||
{
|
||||
/* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
|
||||
if (CheckBuffer((BufferObject *)(self)))
|
||||
return -1; /* ??? */
|
||||
|
||||
return (PyInt)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferItem(PyObject *self, PyInt n)
|
||||
{
|
||||
return RBItem((BufferObject *)(self), n, 1,
|
||||
(PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferSlice(PyObject *self, PyInt lo, PyInt hi)
|
||||
{
|
||||
return RBSlice((BufferObject *)(self), lo, hi, 1,
|
||||
(PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferAppend(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
109
src/if_python.c
109
src/if_python.c
@ -619,6 +619,9 @@ static int initialised = 0;
|
||||
|
||||
#define DESTRUCTOR_FINISH(self) Py_DECREF(self);
|
||||
|
||||
#define WIN_PYTHON_REF(win) win->w_python_ref
|
||||
#define BUF_PYTHON_REF(buf) buf->b_python_ref
|
||||
|
||||
static PyObject *OutputGetattr(PyObject *, char *);
|
||||
static PyObject *BufferGetattr(PyObject *, char *);
|
||||
static PyObject *WindowGetattr(PyObject *, char *);
|
||||
@ -1053,42 +1056,6 @@ static PySequenceMethods BufferAsSeq = {
|
||||
/* Buffer object - Implementation
|
||||
*/
|
||||
|
||||
static PyObject *
|
||||
BufferNew(buf_T *buf)
|
||||
{
|
||||
/* We need to handle deletion of buffers underneath us.
|
||||
* If we add a "b_python_ref" field to the buf_T structure,
|
||||
* then we can get at it in buf_freeall() in vim. We then
|
||||
* need to create only ONE Python object per buffer - if
|
||||
* we try to create a second, just INCREF the existing one
|
||||
* and return it. The (single) Python object referring to
|
||||
* the buffer is stored in "b_python_ref".
|
||||
* Question: what to do on a buf_freeall(). We'll probably
|
||||
* have to either delete the Python object (DECREF it to
|
||||
* zero - a bad idea, as it leaves dangling refs!) or
|
||||
* set the buf_T * value to an invalid value (-1?), which
|
||||
* means we need checks in all access functions... Bah.
|
||||
*/
|
||||
|
||||
BufferObject *self;
|
||||
|
||||
if (buf->b_python_ref != NULL)
|
||||
{
|
||||
self = buf->b_python_ref;
|
||||
Py_INCREF(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
self = PyObject_NEW(BufferObject, &BufferType);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
self->buf = buf;
|
||||
buf->b_python_ref = self;
|
||||
}
|
||||
|
||||
return (PyObject *)(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferGetattr(PyObject *self, char *name)
|
||||
{
|
||||
@ -1106,30 +1073,6 @@ BufferGetattr(PyObject *self, char *name)
|
||||
|
||||
/******************/
|
||||
|
||||
static PyInt
|
||||
BufferLength(PyObject *self)
|
||||
{
|
||||
/* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
|
||||
if (CheckBuffer((BufferObject *)(self)))
|
||||
return -1; /* ??? */
|
||||
|
||||
return (((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferItem(PyObject *self, PyInt n)
|
||||
{
|
||||
return RBItem((BufferObject *)(self), n, 1,
|
||||
(int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferSlice(PyObject *self, PyInt lo, PyInt hi)
|
||||
{
|
||||
return RBSlice((BufferObject *)(self), lo, hi, 1,
|
||||
(int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyInt
|
||||
BufferAssItem(PyObject *self, PyInt n, PyObject *val)
|
||||
{
|
||||
@ -1216,40 +1159,6 @@ static PySequenceMethods BufListAsSeq = {
|
||||
/* Window object - Implementation
|
||||
*/
|
||||
|
||||
static PyObject *
|
||||
WindowNew(win_T *win)
|
||||
{
|
||||
/* We need to handle deletion of windows underneath us.
|
||||
* If we add a "w_python_ref" field to the win_T structure,
|
||||
* then we can get at it in win_free() in vim. We then
|
||||
* need to create only ONE Python object per window - if
|
||||
* we try to create a second, just INCREF the existing one
|
||||
* and return it. The (single) Python object referring to
|
||||
* the window is stored in "w_python_ref".
|
||||
* On a win_free() we set the Python object's win_T* field
|
||||
* to an invalid value. We trap all uses of a window
|
||||
* object, and reject them if the win_T* field is invalid.
|
||||
*/
|
||||
|
||||
WindowObject *self;
|
||||
|
||||
if (win->w_python_ref)
|
||||
{
|
||||
self = win->w_python_ref;
|
||||
Py_INCREF(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
self = PyObject_NEW(WindowObject, &WindowType);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
self->win = win;
|
||||
win->w_python_ref = self;
|
||||
}
|
||||
|
||||
return (PyObject *)(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
WindowGetattr(PyObject *self, char *name)
|
||||
{
|
||||
@ -1289,11 +1198,11 @@ static PySequenceMethods WinListAsSeq = {
|
||||
void
|
||||
python_buffer_free(buf_T *buf)
|
||||
{
|
||||
if (buf->b_python_ref != NULL)
|
||||
if (BUF_PYTHON_REF(buf) != NULL)
|
||||
{
|
||||
BufferObject *bp = buf->b_python_ref;
|
||||
BufferObject *bp = BUF_PYTHON_REF(buf);
|
||||
bp->buf = INVALID_BUFFER_VALUE;
|
||||
buf->b_python_ref = NULL;
|
||||
BUF_PYTHON_REF(buf) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1301,11 +1210,11 @@ python_buffer_free(buf_T *buf)
|
||||
void
|
||||
python_window_free(win_T *win)
|
||||
{
|
||||
if (win->w_python_ref != NULL)
|
||||
if (WIN_PYTHON_REF(win) != NULL)
|
||||
{
|
||||
WindowObject *wp = win->w_python_ref;
|
||||
WindowObject *wp = WIN_PYTHON_REF(win);
|
||||
wp->win = INVALID_WINDOW_VALUE;
|
||||
win->w_python_ref = NULL;
|
||||
WIN_PYTHON_REF(win) = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
110
src/if_python3.c
110
src/if_python3.c
@ -621,6 +621,9 @@ static int py3initialised = 0;
|
||||
|
||||
#define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self);
|
||||
|
||||
#define WIN_PYTHON_REF(win) win->w_python3_ref
|
||||
#define BUF_PYTHON_REF(buf) buf->b_python3_ref
|
||||
|
||||
static void
|
||||
call_PyObject_Free(void *p)
|
||||
{
|
||||
@ -1067,45 +1070,9 @@ static PyMappingMethods BufferAsMapping = {
|
||||
};
|
||||
|
||||
|
||||
/* Buffer object - Definitions
|
||||
/* Buffer object
|
||||
*/
|
||||
|
||||
static PyObject *
|
||||
BufferNew(buf_T *buf)
|
||||
{
|
||||
/* We need to handle deletion of buffers underneath us.
|
||||
* If we add a "b_python3_ref" field to the buf_T structure,
|
||||
* then we can get at it in buf_freeall() in vim. We then
|
||||
* need to create only ONE Python object per buffer - if
|
||||
* we try to create a second, just INCREF the existing one
|
||||
* and return it. The (single) Python object referring to
|
||||
* the buffer is stored in "b_python3_ref".
|
||||
* Question: what to do on a buf_freeall(). We'll probably
|
||||
* have to either delete the Python object (DECREF it to
|
||||
* zero - a bad idea, as it leaves dangling refs!) or
|
||||
* set the buf_T * value to an invalid value (-1?), which
|
||||
* means we need checks in all access functions... Bah.
|
||||
*/
|
||||
|
||||
BufferObject *self;
|
||||
|
||||
if (buf->b_python3_ref != NULL)
|
||||
{
|
||||
self = buf->b_python3_ref;
|
||||
Py_INCREF(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
self = PyObject_NEW(BufferObject, &BufferType);
|
||||
buf->b_python3_ref = self;
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
self->buf = buf;
|
||||
}
|
||||
|
||||
return (PyObject *)(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferGetattro(PyObject *self, PyObject*nameobj)
|
||||
{
|
||||
@ -1132,29 +1099,6 @@ BufferDir(PyObject *self UNUSED, PyObject *args UNUSED)
|
||||
|
||||
/******************/
|
||||
|
||||
static Py_ssize_t
|
||||
BufferLength(PyObject *self)
|
||||
{
|
||||
if (CheckBuffer((BufferObject *)(self)))
|
||||
return -1;
|
||||
|
||||
return (Py_ssize_t)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferItem(PyObject *self, Py_ssize_t n)
|
||||
{
|
||||
return RBItem((BufferObject *)(self), n, 1,
|
||||
(Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
|
||||
{
|
||||
return RBSlice((BufferObject *)(self), lo, hi, 1,
|
||||
(Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
BufferSubscript(PyObject *self, PyObject* idx)
|
||||
{
|
||||
@ -1341,40 +1285,6 @@ static PySequenceMethods BufListAsSeq = {
|
||||
/* Window object - Implementation
|
||||
*/
|
||||
|
||||
static PyObject *
|
||||
WindowNew(win_T *win)
|
||||
{
|
||||
/* We need to handle deletion of windows underneath us.
|
||||
* If we add a "w_python3_ref" field to the win_T structure,
|
||||
* then we can get at it in win_free() in vim. We then
|
||||
* need to create only ONE Python object per window - if
|
||||
* we try to create a second, just INCREF the existing one
|
||||
* and return it. The (single) Python object referring to
|
||||
* the window is stored in "w_python3_ref".
|
||||
* On a win_free() we set the Python object's win_T* field
|
||||
* to an invalid value. We trap all uses of a window
|
||||
* object, and reject them if the win_T* field is invalid.
|
||||
*/
|
||||
|
||||
WindowObject *self;
|
||||
|
||||
if (win->w_python3_ref)
|
||||
{
|
||||
self = win->w_python3_ref;
|
||||
Py_INCREF(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
self = PyObject_NEW(WindowObject, &WindowType);
|
||||
if (self == NULL)
|
||||
return NULL;
|
||||
self->win = win;
|
||||
win->w_python3_ref = self;
|
||||
}
|
||||
|
||||
return (PyObject *)(self);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
WindowGetattro(PyObject *self, PyObject *nameobj)
|
||||
{
|
||||
@ -1575,11 +1485,11 @@ FunctionGetattro(PyObject *self, PyObject *nameobj)
|
||||
void
|
||||
python3_buffer_free(buf_T *buf)
|
||||
{
|
||||
if (buf->b_python3_ref != NULL)
|
||||
if (BUF_PYTHON_REF(buf) != NULL)
|
||||
{
|
||||
BufferObject *bp = buf->b_python3_ref;
|
||||
BufferObject *bp = BUF_PYTHON_REF(buf);
|
||||
bp->buf = INVALID_BUFFER_VALUE;
|
||||
buf->b_python3_ref = NULL;
|
||||
BUF_PYTHON_REF(buf) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1587,11 +1497,11 @@ python3_buffer_free(buf_T *buf)
|
||||
void
|
||||
python3_window_free(win_T *win)
|
||||
{
|
||||
if (win->w_python3_ref != NULL)
|
||||
if (WIN_PYTHON_REF(win) != NULL)
|
||||
{
|
||||
WindowObject *wp = win->w_python3_ref;
|
||||
WindowObject *wp = WIN_PYTHON_REF(win);
|
||||
wp->win = INVALID_WINDOW_VALUE;
|
||||
win->w_python3_ref = NULL;
|
||||
WIN_PYTHON_REF(win) = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -728,6 +728,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
937,
|
||||
/**/
|
||||
936,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user