diff --git a/7.3.937 b/7.3.937 new file mode 100644 index 0000000..a9bd210 --- /dev/null +++ b/7.3.937 @@ -0,0 +1,616 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.3.937 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.3.937 +Problem: More can be shared between Python 2 and 3. +Solution: Move code to if_py_both.h. (ZyX) +Files: src/if_python.c, src/if_python3.c, src/if_py_both.h + + +*** ../vim-7.3.936/src/if_python.c 2013-05-06 04:21:35.000000000 +0200 +--- src/if_python.c 2013-05-12 18:31:20.000000000 +0200 +*************** +*** 619,624 **** +--- 619,627 ---- + + #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,1095 **** + */ + + 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; +--- 1057,1062 ---- +*************** +*** 1107,1136 **** + /******************/ + + 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, +--- 1074,1079 ---- +*************** +*** 1217,1256 **** + */ + + 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; +--- 1160,1165 ---- +*************** +*** 1289,1299 **** + void + python_buffer_free(buf_T *buf) + { +! if (buf->b_python_ref != NULL) + { +! BufferObject *bp = buf->b_python_ref; + bp->buf = INVALID_BUFFER_VALUE; +! buf->b_python_ref = NULL; + } + } + +--- 1198,1208 ---- + void + python_buffer_free(buf_T *buf) + { +! if (BUF_PYTHON_REF(buf) != NULL) + { +! BufferObject *bp = BUF_PYTHON_REF(buf); + bp->buf = INVALID_BUFFER_VALUE; +! BUF_PYTHON_REF(buf) = NULL; + } + } + +*************** +*** 1301,1311 **** + void + python_window_free(win_T *win) + { +! if (win->w_python_ref != NULL) + { +! WindowObject *wp = win->w_python_ref; + wp->win = INVALID_WINDOW_VALUE; +! win->w_python_ref = NULL; + } + } + #endif +--- 1210,1220 ---- + void + python_window_free(win_T *win) + { +! if (WIN_PYTHON_REF(win) != NULL) + { +! WindowObject *wp = WIN_PYTHON_REF(win); + wp->win = INVALID_WINDOW_VALUE; +! WIN_PYTHON_REF(win) = NULL; + } + } + #endif +*** ../vim-7.3.936/src/if_python3.c 2013-05-06 04:21:35.000000000 +0200 +--- src/if_python3.c 2013-05-12 18:31:20.000000000 +0200 +*************** +*** 621,626 **** +--- 621,629 ---- + + #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,1112 **** + }; + + +! /* Buffer object - Definitions + */ + + 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; +--- 1070,1079 ---- + }; + + +! /* Buffer object + */ + + static PyObject * + BufferGetattro(PyObject *self, PyObject*nameobj) + { + PyObject *r; +*************** +*** 1132,1160 **** + + /******************/ + +- 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) + { +--- 1099,1104 ---- +*************** +*** 1342,1381 **** + */ + + 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; +--- 1286,1291 ---- +*************** +*** 1575,1585 **** + void + python3_buffer_free(buf_T *buf) + { +! if (buf->b_python3_ref != NULL) + { +! BufferObject *bp = buf->b_python3_ref; + bp->buf = INVALID_BUFFER_VALUE; +! buf->b_python3_ref = NULL; + } + } + +--- 1485,1495 ---- + void + python3_buffer_free(buf_T *buf) + { +! if (BUF_PYTHON_REF(buf) != NULL) + { +! BufferObject *bp = BUF_PYTHON_REF(buf); + bp->buf = INVALID_BUFFER_VALUE; +! BUF_PYTHON_REF(buf) = NULL; + } + } + +*************** +*** 1587,1597 **** + void + python3_window_free(win_T *win) + { +! if (win->w_python3_ref != NULL) + { +! WindowObject *wp = win->w_python3_ref; + wp->win = INVALID_WINDOW_VALUE; +! win->w_python3_ref = NULL; + } + } + #endif +--- 1497,1507 ---- + void + python3_window_free(win_T *win) + { +! if (WIN_PYTHON_REF(win) != NULL) + { +! WindowObject *wp = WIN_PYTHON_REF(win); + wp->win = INVALID_WINDOW_VALUE; +! WIN_PYTHON_REF(win) = NULL; + } + } + #endif +*** ../vim-7.3.936/src/if_py_both.h 2013-05-06 06:26:10.000000000 +0200 +--- src/if_py_both.h 2013-05-12 18:31:20.000000000 +0200 +*************** +*** 1782,1792 **** +--- 1782,1832 ---- + 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,1815 **** + return OptionsNew(SREQ_WIN, this->win, (checkfun) CheckWindow, + (PyObject *) this); + else if (strcmp(name,"__members__") == 0) +! return Py_BuildValue("[sssss]", "buffer", "cursor", "height", "vars", + "options"); + else + return NULL; +--- 1849,1855 ---- + return OptionsNew(SREQ_WIN, this->win, (checkfun) CheckWindow, + (PyObject *) this); + else if (strcmp(name,"__members__") == 0) +! return Py_BuildValue("[ssssss]", "buffer", "cursor", "height", "vars", + "options"); + else + return NULL; +*************** +*** 1821,1831 **** + 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 + + DESTRUCTOR_FINISH(self); + } +--- 1861,1867 ---- + WindowObject *this = (WindowObject *)(self); + + if (this->win && this->win != INVALID_WINDOW_VALUE) +! WIN_PYTHON_REF(this->win) = NULL; + + DESTRUCTOR_FINISH(self); + } +*************** +*** 2756,2771 **** + 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 + + DESTRUCTOR_FINISH(self); + } + + static PyObject * + BufferAttr(BufferObject *this, char *name) + { + if (strcmp(name, "name") == 0) +--- 2792,2842 ---- + BufferObject *this = (BufferObject *)(self); + + if (this->buf && this->buf != INVALID_BUFFER_VALUE) +! 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,2788 **** +--- 2854,2883 ---- + 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) + { +*** ../vim-7.3.936/src/version.c 2013-05-12 14:10:41.000000000 +0200 +--- src/version.c 2013-05-12 18:44:01.000000000 +0200 +*************** +*** 730,731 **** +--- 730,733 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 937, + /**/ + +-- +ARTHUR: Well, I can't just call you `Man'. +DENNIS: Well, you could say `Dennis'. +ARTHUR: Well, I didn't know you were called `Dennis.' +DENNIS: Well, you didn't bother to find out, did you? + The Quest for the Holy Grail (Monty Python) + + /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ an exciting new programming language -- http://www.Zimbu.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org ///