# HG changeset patch # User Bram Moolenaar # Date 1368377088 -7200 # Node ID 8ec7323f417d998685afc26bbb4e466eb0204352 # Parent 249da4a43d4c9002bd70382143506ef8c4c1a85d 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) diff --git a/src/if_py_both.h b/src/if_py_both.h --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -1782,11 +1782,51 @@ 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) { if (strcmp(name, "buffer") == 0) @@ -1809,7 +1849,7 @@ WindowAttr(WindowObject *this, char *nam 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,16 +2792,51 @@ 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) { if (strcmp(name, "name") == 0) @@ -2783,6 +2854,30 @@ BufferAttr(BufferObject *this, char *nam 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) { diff --git a/src/if_python.c b/src/if_python.c --- a/src/if_python.c +++ b/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 *); @@ -1054,42 +1057,6 @@ static PySequenceMethods BufferAsSeq = { */ 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) { PyObject *r; @@ -1107,30 +1074,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) { return RBAsItem((BufferObject *)(self), n, val, 1, @@ -1217,40 +1160,6 @@ static PySequenceMethods BufListAsSeq = */ 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) { PyObject *r; @@ -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 diff --git a/src/if_python3.c b/src/if_python3.c --- a/src/if_python3.c +++ b/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,46 +1070,10 @@ 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) { PyObject *r; @@ -1132,29 +1099,6 @@ BufferDir(PyObject *self UNUSED, PyObjec /******************/ - 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) { @@ -1342,40 +1286,6 @@ static PySequenceMethods BufListAsSeq = */ 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) { PyObject *r; @@ -1575,11 +1485,11 @@ FunctionGetattro(PyObject *self, PyObjec 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 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 937, +/**/ 936, /**/ 935,