changeset 4377:8ec7323f417d v7.3.937

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)
author Bram Moolenaar <bram@vim.org>
date Sun, 12 May 2013 18:44:48 +0200
parents 249da4a43d4c
children b6df5640cd64
files src/if_py_both.h src/if_python.c src/if_python3.c src/version.c
diffstat 4 files changed, 127 insertions(+), 211 deletions(-) [+]
line wrap: on
line diff
--- 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)
 {
--- 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
--- 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
--- 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,