| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.937 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| 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 |
| |
| |
| |
| |
| |
| *** 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 **** |
| / |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| *** 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 |
| |
| |
| |
| *** 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 **** |
| |
| / |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| *** 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 |
| |
| |
| |
| *** 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) |
| { |
| |
| |
| |
| *** 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 /// |