Karsten Hopp 9f9890
To: vim_dev@googlegroups.com
Karsten Hopp 9f9890
Subject: Patch 7.3.947
Karsten Hopp 9f9890
Fcc: outbox
Karsten Hopp 9f9890
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 9f9890
Mime-Version: 1.0
Karsten Hopp 9f9890
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 9f9890
Content-Transfer-Encoding: 8bit
Karsten Hopp 9f9890
------------
Karsten Hopp 9f9890
Karsten Hopp 9f9890
Patch 7.3.947
Karsten Hopp 9f9890
Problem:    Python: No iterator for vim.list and vim.bufferlist.
Karsten Hopp 9f9890
Solution:   Add the iterators. Also fix name of FunctionType. Add tests for
Karsten Hopp 9f9890
	    vim.buffers.  (ZyX)
Karsten Hopp 9f9890
Files:	    runtime/doc/if_pyth.txt, src/eval.c, src/if_py_both.h,
Karsten Hopp 9f9890
	    src/if_python3.c, src/if_python.c, src/proto/eval.pro,
Karsten Hopp 9f9890
	    src/testdir/test86.in, src/testdir/test86.ok,
Karsten Hopp 9f9890
	    src/testdir/test87.in, src/testdir/test87.ok
Karsten Hopp 9f9890
Karsten Hopp 9f9890
Karsten Hopp 9f9890
*** ../vim-7.3.946/runtime/doc/if_pyth.txt	2013-05-15 13:38:41.000000000 +0200
Karsten Hopp 9f9890
--- runtime/doc/if_pyth.txt	2013-05-15 14:24:11.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 214,219 ****
Karsten Hopp 9f9890
--- 214,220 ----
Karsten Hopp 9f9890
  	    :py b = vim.buffers[i]	# Indexing (read-only)
Karsten Hopp 9f9890
  	    :py b in vim.buffers	# Membership test
Karsten Hopp 9f9890
  	    :py n = len(vim.buffers)	# Number of elements
Karsten Hopp 9f9890
+ 	    :py for b in vim.buffers:	# Iterating over buffer list
Karsten Hopp 9f9890
  <
Karsten Hopp 9f9890
  vim.windows						*python-windows*
Karsten Hopp 9f9890
  	A sequence object providing access to the list of vim windows.  The
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/eval.c	2013-05-06 04:50:26.000000000 +0200
Karsten Hopp 9f9890
--- src/eval.c	2013-05-15 14:24:11.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 390,397 ****
Karsten Hopp 9f9890
  static void clear_lval __ARGS((lval_T *lp));
Karsten Hopp 9f9890
  static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op));
Karsten Hopp 9f9890
  static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u  *op));
Karsten Hopp 9f9890
- static void list_add_watch __ARGS((list_T *l, listwatch_T *lw));
Karsten Hopp 9f9890
- static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem));
Karsten Hopp 9f9890
  static void list_fix_watch __ARGS((list_T *l, listitem_T *item));
Karsten Hopp 9f9890
  static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep));
Karsten Hopp 9f9890
  static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit));
Karsten Hopp 9f9890
--- 390,395 ----
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 3106,3112 ****
Karsten Hopp 9f9890
  /*
Karsten Hopp 9f9890
   * Add a watcher to a list.
Karsten Hopp 9f9890
   */
Karsten Hopp 9f9890
!     static void
Karsten Hopp 9f9890
  list_add_watch(l, lw)
Karsten Hopp 9f9890
      list_T	*l;
Karsten Hopp 9f9890
      listwatch_T	*lw;
Karsten Hopp 9f9890
--- 3104,3110 ----
Karsten Hopp 9f9890
  /*
Karsten Hopp 9f9890
   * Add a watcher to a list.
Karsten Hopp 9f9890
   */
Karsten Hopp 9f9890
!     void
Karsten Hopp 9f9890
  list_add_watch(l, lw)
Karsten Hopp 9f9890
      list_T	*l;
Karsten Hopp 9f9890
      listwatch_T	*lw;
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 3119,3125 ****
Karsten Hopp 9f9890
   * Remove a watcher from a list.
Karsten Hopp 9f9890
   * No warning when it isn't found...
Karsten Hopp 9f9890
   */
Karsten Hopp 9f9890
!     static void
Karsten Hopp 9f9890
  list_rem_watch(l, lwrem)
Karsten Hopp 9f9890
      list_T	*l;
Karsten Hopp 9f9890
      listwatch_T	*lwrem;
Karsten Hopp 9f9890
--- 3117,3123 ----
Karsten Hopp 9f9890
   * Remove a watcher from a list.
Karsten Hopp 9f9890
   * No warning when it isn't found...
Karsten Hopp 9f9890
   */
Karsten Hopp 9f9890
!     void
Karsten Hopp 9f9890
  list_rem_watch(l, lwrem)
Karsten Hopp 9f9890
      list_T	*l;
Karsten Hopp 9f9890
      listwatch_T	*lwrem;
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/if_py_both.h	2013-05-15 13:38:41.000000000 +0200
Karsten Hopp 9f9890
--- src/if_py_both.h	2013-05-15 14:24:11.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 531,596 ****
Karsten Hopp 9f9890
  };
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
  /*
Karsten Hopp 9f9890
!  * Buffer list object - Implementation
Karsten Hopp 9f9890
   */
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
! static PyTypeObject BufMapType;
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
  typedef struct
Karsten Hopp 9f9890
  {
Karsten Hopp 9f9890
      PyObject_HEAD
Karsten Hopp 9f9890
! } BufMapObject;
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     static PyInt
Karsten Hopp 9f9890
! BufMapLength(PyObject *self UNUSED)
Karsten Hopp 9f9890
  {
Karsten Hopp 9f9890
!     buf_T	*b = firstbuf;
Karsten Hopp 9f9890
!     PyInt	n = 0;
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     while (b)
Karsten Hopp 9f9890
!     {
Karsten Hopp 9f9890
! 	++n;
Karsten Hopp 9f9890
! 	b = b->b_next;
Karsten Hopp 9f9890
!     }
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     return n;
Karsten Hopp 9f9890
  }
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     static PyObject *
Karsten Hopp 9f9890
! BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
Karsten Hopp 9f9890
  {
Karsten Hopp 9f9890
!     buf_T	*b;
Karsten Hopp 9f9890
!     int		bnr;
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
! #if PY_MAJOR_VERSION < 3
Karsten Hopp 9f9890
!     if (PyInt_Check(keyObject))
Karsten Hopp 9f9890
! 	bnr = PyInt_AsLong(keyObject);
Karsten Hopp 9f9890
!     else
Karsten Hopp 9f9890
! #endif
Karsten Hopp 9f9890
!     if (PyLong_Check(keyObject))
Karsten Hopp 9f9890
! 	bnr = PyLong_AsLong(keyObject);
Karsten Hopp 9f9890
!     else
Karsten Hopp 9f9890
!     {
Karsten Hopp 9f9890
! 	PyErr_SetString(PyExc_ValueError, _("key must be integer"));
Karsten Hopp 9f9890
! 	return NULL;
Karsten Hopp 9f9890
!     }
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     b = buflist_findnr(bnr);
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     if (b)
Karsten Hopp 9f9890
! 	return BufferNew(b);
Karsten Hopp 9f9890
!     else
Karsten Hopp 9f9890
!     {
Karsten Hopp 9f9890
! 	PyErr_SetString(PyExc_KeyError, _("no such buffer"));
Karsten Hopp 9f9890
! 	return NULL;
Karsten Hopp 9f9890
!     }
Karsten Hopp 9f9890
  }
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
! static PyMappingMethods BufMapAsMapping = {
Karsten Hopp 9f9890
!     (lenfunc)       BufMapLength,
Karsten Hopp 9f9890
!     (binaryfunc)    BufMapItem,
Karsten Hopp 9f9890
!     (objobjargproc) 0,
Karsten Hopp 9f9890
! };
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
  typedef struct pylinkedlist_S {
Karsten Hopp 9f9890
      struct pylinkedlist_S	*pll_next;
Karsten Hopp 9f9890
--- 531,592 ----
Karsten Hopp 9f9890
  };
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
  /*
Karsten Hopp 9f9890
!  * Generic iterator object
Karsten Hopp 9f9890
   */
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
! static PyTypeObject IterType;
Karsten Hopp 9f9890
! 
Karsten Hopp 9f9890
! typedef PyObject *(*nextfun)(void **);
Karsten Hopp 9f9890
! typedef void (*destructorfun)(void *);
Karsten Hopp 9f9890
! 
Karsten Hopp 9f9890
! /* Main purpose of this object is removing the need for do python initialization 
Karsten Hopp 9f9890
!  * (i.e. PyType_Ready and setting type attributes) for a big bunch of objects.
Karsten Hopp 9f9890
!  */
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
  typedef struct
Karsten Hopp 9f9890
  {
Karsten Hopp 9f9890
      PyObject_HEAD
Karsten Hopp 9f9890
!     void *cur;
Karsten Hopp 9f9890
!     nextfun next;
Karsten Hopp 9f9890
!     destructorfun destruct;
Karsten Hopp 9f9890
! } IterObject;
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     static PyObject *
Karsten Hopp 9f9890
! IterNew(void *start, destructorfun destruct, nextfun next)
Karsten Hopp 9f9890
  {
Karsten Hopp 9f9890
!     IterObject *self;
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     self = PyObject_NEW(IterObject, &IterType);
Karsten Hopp 9f9890
!     self->cur = start;
Karsten Hopp 9f9890
!     self->next = next;
Karsten Hopp 9f9890
!     self->destruct = destruct;
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     return (PyObject *)(self);
Karsten Hopp 9f9890
  }
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     static void
Karsten Hopp 9f9890
! IterDestructor(PyObject *self)
Karsten Hopp 9f9890
  {
Karsten Hopp 9f9890
!     IterObject *this = (IterObject *)(self);
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     this->destruct(this->cur);
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     DESTRUCTOR_FINISH(self);
Karsten Hopp 9f9890
! }
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     static PyObject *
Karsten Hopp 9f9890
! IterNext(PyObject *self)
Karsten Hopp 9f9890
! {
Karsten Hopp 9f9890
!     IterObject *this = (IterObject *)(self);
Karsten Hopp 9f9890
! 
Karsten Hopp 9f9890
!     return this->next(&this->cur);
Karsten Hopp 9f9890
  }
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
!     static PyObject *
Karsten Hopp 9f9890
! IterIter(PyObject *self)
Karsten Hopp 9f9890
! {
Karsten Hopp 9f9890
!     return self;
Karsten Hopp 9f9890
! }
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
  typedef struct pylinkedlist_S {
Karsten Hopp 9f9890
      struct pylinkedlist_S	*pll_next;
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 990,995 ****
Karsten Hopp 9f9890
--- 986,1040 ----
Karsten Hopp 9f9890
      return list;
Karsten Hopp 9f9890
  }
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
+ typedef struct
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     listwatch_T	lw;
Karsten Hopp 9f9890
+     list_T	*list;
Karsten Hopp 9f9890
+ } listiterinfo_T;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     static void
Karsten Hopp 9f9890
+ ListIterDestruct(listiterinfo_T *lii)
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     list_rem_watch(lii->list, &lii->lw);
Karsten Hopp 9f9890
+     PyMem_Free(lii);
Karsten Hopp 9f9890
+ }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     static PyObject *
Karsten Hopp 9f9890
+ ListIterNext(listiterinfo_T **lii)
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     PyObject	*r;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     if (!((*lii)->lw.lw_item))
Karsten Hopp 9f9890
+ 	return NULL;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
Karsten Hopp 9f9890
+ 	return NULL;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     return r;
Karsten Hopp 9f9890
+ }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     static PyObject *
Karsten Hopp 9f9890
+ ListIter(PyObject *self)
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     listiterinfo_T	*lii;
Karsten Hopp 9f9890
+     list_T	*l = ((ListObject *) (self))->list;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     if (!(lii = PyMem_New(listiterinfo_T, 1)))
Karsten Hopp 9f9890
+     {
Karsten Hopp 9f9890
+ 	PyErr_NoMemory();
Karsten Hopp 9f9890
+ 	return NULL;
Karsten Hopp 9f9890
+     }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     list_add_watch(l, &lii->lw);
Karsten Hopp 9f9890
+     lii->lw.lw_item = l->lv_first;
Karsten Hopp 9f9890
+     lii->list = l;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     return IterNew(lii,
Karsten Hopp 9f9890
+ 	    (destructorfun) ListIterDestruct, (nextfun) ListIterNext);
Karsten Hopp 9f9890
+ }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
      static int
Karsten Hopp 9f9890
  ListAssItem(PyObject *self, Py_ssize_t index, PyObject *obj)
Karsten Hopp 9f9890
  {
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 2869,2874 ****
Karsten Hopp 9f9890
--- 2914,3029 ----
Karsten Hopp 9f9890
      { NULL,	    NULL,		0,	    NULL }
Karsten Hopp 9f9890
  };
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
+ /*
Karsten Hopp 9f9890
+  * Buffer list object - Implementation
Karsten Hopp 9f9890
+  */
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ static PyTypeObject BufMapType;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ typedef struct
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     PyObject_HEAD
Karsten Hopp 9f9890
+ } BufMapObject;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     static PyInt
Karsten Hopp 9f9890
+ BufMapLength(PyObject *self UNUSED)
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     buf_T	*b = firstbuf;
Karsten Hopp 9f9890
+     PyInt	n = 0;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     while (b)
Karsten Hopp 9f9890
+     {
Karsten Hopp 9f9890
+ 	++n;
Karsten Hopp 9f9890
+ 	b = b->b_next;
Karsten Hopp 9f9890
+     }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     return n;
Karsten Hopp 9f9890
+ }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     static PyObject *
Karsten Hopp 9f9890
+ BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     buf_T	*b;
Karsten Hopp 9f9890
+     int		bnr;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ #if PY_MAJOR_VERSION < 3
Karsten Hopp 9f9890
+     if (PyInt_Check(keyObject))
Karsten Hopp 9f9890
+ 	bnr = PyInt_AsLong(keyObject);
Karsten Hopp 9f9890
+     else
Karsten Hopp 9f9890
+ #endif
Karsten Hopp 9f9890
+     if (PyLong_Check(keyObject))
Karsten Hopp 9f9890
+ 	bnr = PyLong_AsLong(keyObject);
Karsten Hopp 9f9890
+     else
Karsten Hopp 9f9890
+     {
Karsten Hopp 9f9890
+ 	PyErr_SetString(PyExc_ValueError, _("key must be integer"));
Karsten Hopp 9f9890
+ 	return NULL;
Karsten Hopp 9f9890
+     }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     b = buflist_findnr(bnr);
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     if (b)
Karsten Hopp 9f9890
+ 	return BufferNew(b);
Karsten Hopp 9f9890
+     else
Karsten Hopp 9f9890
+     {
Karsten Hopp 9f9890
+ 	PyErr_SetString(PyExc_KeyError, _("no such buffer"));
Karsten Hopp 9f9890
+ 	return NULL;
Karsten Hopp 9f9890
+     }
Karsten Hopp 9f9890
+ }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     static void
Karsten Hopp 9f9890
+ BufMapIterDestruct(PyObject *buffer)
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     /* Iteration was stopped before all buffers were processed */
Karsten Hopp 9f9890
+     if (buffer)
Karsten Hopp 9f9890
+     {
Karsten Hopp 9f9890
+ 	Py_DECREF(buffer);
Karsten Hopp 9f9890
+     }
Karsten Hopp 9f9890
+ }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     static PyObject *
Karsten Hopp 9f9890
+ BufMapIterNext(PyObject **buffer)
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     PyObject	*next;
Karsten Hopp 9f9890
+     PyObject	*r;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     if (!*buffer)
Karsten Hopp 9f9890
+ 	return NULL;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     r = *buffer;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     if (CheckBuffer((BufferObject *)(r)))
Karsten Hopp 9f9890
+     {
Karsten Hopp 9f9890
+ 	*buffer = NULL;
Karsten Hopp 9f9890
+ 	return NULL;
Karsten Hopp 9f9890
+     }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     if (!((BufferObject *)(r))->buf->b_next)
Karsten Hopp 9f9890
+ 	next = NULL;
Karsten Hopp 9f9890
+     else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
Karsten Hopp 9f9890
+ 	return NULL;
Karsten Hopp 9f9890
+     *buffer = next;
Karsten Hopp 9f9890
+     /* Do not increment reference: we no longer hold it (decref), but whoever on 
Karsten Hopp 9f9890
+      * other side will hold (incref). Decref+incref = nothing.
Karsten Hopp 9f9890
+      */
Karsten Hopp 9f9890
+     return r;
Karsten Hopp 9f9890
+ }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     static PyObject *
Karsten Hopp 9f9890
+ BufMapIter(PyObject *self UNUSED)
Karsten Hopp 9f9890
+ {
Karsten Hopp 9f9890
+     PyObject *buffer;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+     buffer = BufferNew(firstbuf);
Karsten Hopp 9f9890
+     return IterNew(buffer,
Karsten Hopp 9f9890
+ 	    (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext);
Karsten Hopp 9f9890
+ }
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ static PyMappingMethods BufMapAsMapping = {
Karsten Hopp 9f9890
+     (lenfunc)       BufMapLength,
Karsten Hopp 9f9890
+     (binaryfunc)    BufMapItem,
Karsten Hopp 9f9890
+     (objobjargproc) 0,
Karsten Hopp 9f9890
+ };
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
  /* Current items object
Karsten Hopp 9f9890
   */
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 3383,3388 ****
Karsten Hopp 9f9890
--- 3538,3551 ----
Karsten Hopp 9f9890
      OutputType.tp_setattr = OutputSetattr;
Karsten Hopp 9f9890
  #endif
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
+     vim_memset(&IterType, 0, sizeof(IterType));
Karsten Hopp 9f9890
+     IterType.tp_name = "vim.iter";
Karsten Hopp 9f9890
+     IterType.tp_basicsize = sizeof(IterObject);
Karsten Hopp 9f9890
+     IterType.tp_flags = Py_TPFLAGS_DEFAULT;
Karsten Hopp 9f9890
+     IterType.tp_doc = "generic iterator object";
Karsten Hopp 9f9890
+     IterType.tp_iter = IterIter;
Karsten Hopp 9f9890
+     IterType.tp_iternext = IterNext;
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
      vim_memset(&BufferType, 0, sizeof(BufferType));
Karsten Hopp 9f9890
      BufferType.tp_name = "vim.buffer";
Karsten Hopp 9f9890
      BufferType.tp_basicsize = sizeof(BufferType);
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 3426,3431 ****
Karsten Hopp 9f9890
--- 3589,3595 ----
Karsten Hopp 9f9890
      BufMapType.tp_basicsize = sizeof(BufMapObject);
Karsten Hopp 9f9890
      BufMapType.tp_as_mapping = &BufMapAsMapping;
Karsten Hopp 9f9890
      BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Karsten Hopp 9f9890
+     BufMapType.tp_iter = BufMapIter;
Karsten Hopp 9f9890
      BufferType.tp_doc = "vim buffer list";
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
      vim_memset(&WinListType, 0, sizeof(WinListType));
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 3492,3497 ****
Karsten Hopp 9f9890
--- 3656,3662 ----
Karsten Hopp 9f9890
      ListType.tp_flags = Py_TPFLAGS_DEFAULT;
Karsten Hopp 9f9890
      ListType.tp_doc = "list pushing modifications to vim structure";
Karsten Hopp 9f9890
      ListType.tp_methods = ListMethods;
Karsten Hopp 9f9890
+     ListType.tp_iter = ListIter;
Karsten Hopp 9f9890
  #if PY_MAJOR_VERSION >= 3
Karsten Hopp 9f9890
      ListType.tp_getattro = ListGetattro;
Karsten Hopp 9f9890
      ListType.tp_setattro = ListSetattro;
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 3501,3507 ****
Karsten Hopp 9f9890
  #endif
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
      vim_memset(&FunctionType, 0, sizeof(FunctionType));
Karsten Hopp 9f9890
!     FunctionType.tp_name = "vim.list";
Karsten Hopp 9f9890
      FunctionType.tp_basicsize = sizeof(FunctionObject);
Karsten Hopp 9f9890
      FunctionType.tp_dealloc = FunctionDestructor;
Karsten Hopp 9f9890
      FunctionType.tp_call = FunctionCall;
Karsten Hopp 9f9890
--- 3666,3672 ----
Karsten Hopp 9f9890
  #endif
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
      vim_memset(&FunctionType, 0, sizeof(FunctionType));
Karsten Hopp 9f9890
!     FunctionType.tp_name = "vim.function";
Karsten Hopp 9f9890
      FunctionType.tp_basicsize = sizeof(FunctionObject);
Karsten Hopp 9f9890
      FunctionType.tp_dealloc = FunctionDestructor;
Karsten Hopp 9f9890
      FunctionType.tp_call = FunctionCall;
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/if_python3.c	2013-05-15 13:38:41.000000000 +0200
Karsten Hopp 9f9890
--- src/if_python3.c	2013-05-15 14:24:11.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 1519,1524 ****
Karsten Hopp 9f9890
--- 1519,1525 ----
Karsten Hopp 9f9890
      /* The special value is removed from sys.path in Python3_Init(). */
Karsten Hopp 9f9890
      static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
+     PyType_Ready(&IterType);
Karsten Hopp 9f9890
      PyType_Ready(&BufferType);
Karsten Hopp 9f9890
      PyType_Ready(&RangeType);
Karsten Hopp 9f9890
      PyType_Ready(&WindowType);
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/if_python.c	2013-05-15 13:38:41.000000000 +0200
Karsten Hopp 9f9890
--- src/if_python.c	2013-05-15 14:24:11.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 1219,1224 ****
Karsten Hopp 9f9890
--- 1219,1225 ----
Karsten Hopp 9f9890
      static char *(argv[2]) = {"/must>not&exist/foo", NULL};
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
      /* Fixups... */
Karsten Hopp 9f9890
+     PyType_Ready(&IterType);
Karsten Hopp 9f9890
      PyType_Ready(&BufferType);
Karsten Hopp 9f9890
      PyType_Ready(&RangeType);
Karsten Hopp 9f9890
      PyType_Ready(&WindowType);
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/proto/eval.pro	2013-05-06 03:52:44.000000000 +0200
Karsten Hopp 9f9890
--- src/proto/eval.pro	2013-05-15 14:24:11.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 127,130 ****
Karsten Hopp 9f9890
--- 127,132 ----
Karsten Hopp 9f9890
  char_u *do_string_sub __ARGS((char_u *str, char_u *pat, char_u *sub, char_u *flags));
Karsten Hopp 9f9890
  int switch_win __ARGS((win_T **, tabpage_T **, win_T *, tabpage_T *));
Karsten Hopp 9f9890
  void restore_win __ARGS((win_T *, tabpage_T *));
Karsten Hopp 9f9890
+ void list_add_watch __ARGS((list_T *l, listwatch_T *lw));
Karsten Hopp 9f9890
+ void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem));
Karsten Hopp 9f9890
  /* vim: set ft=c : */
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/testdir/test86.in	2013-05-12 21:16:17.000000000 +0200
Karsten Hopp 9f9890
--- src/testdir/test86.in	2013-05-15 14:27:21.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 477,482 ****
Karsten Hopp 9f9890
--- 477,485 ----
Karsten Hopp 9f9890
  :   call RecVars(oname)
Karsten Hopp 9f9890
  :endfor
Karsten Hopp 9f9890
  :only
Karsten Hopp 9f9890
+ :for buf in g:bufs[1:]
Karsten Hopp 9f9890
+ :   execute 'bwipeout!' buf
Karsten Hopp 9f9890
+ :endfor
Karsten Hopp 9f9890
  :"
Karsten Hopp 9f9890
  :" Test buffer object
Karsten Hopp 9f9890
  :vnew
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 519,524 ****
Karsten Hopp 9f9890
--- 522,583 ----
Karsten Hopp 9f9890
          # Should not happen in any case
Karsten Hopp 9f9890
          cb.append('No exception for ' + expr)
Karsten Hopp 9f9890
  EOF
Karsten Hopp 9f9890
+ :"
Karsten Hopp 9f9890
+ :" Test vim.buffers object
Karsten Hopp 9f9890
+ :set hidden
Karsten Hopp 9f9890
+ :edit a
Karsten Hopp 9f9890
+ :buffer #
Karsten Hopp 9f9890
+ :edit b
Karsten Hopp 9f9890
+ :buffer #
Karsten Hopp 9f9890
+ :edit c
Karsten Hopp 9f9890
+ :buffer #
Karsten Hopp 9f9890
+ py << EOF
Karsten Hopp 9f9890
+ # Check GCing iterator that was not fully exhausted
Karsten Hopp 9f9890
+ i = iter(vim.buffers)
Karsten Hopp 9f9890
+ cb.append('i:' + str(next(i)))
Karsten Hopp 9f9890
+ # and also check creating more then one iterator at a time
Karsten Hopp 9f9890
+ i2 = iter(vim.buffers)
Karsten Hopp 9f9890
+ cb.append('i2:' + str(next(i2)))
Karsten Hopp 9f9890
+ cb.append('i:' + str(next(i)))
Karsten Hopp 9f9890
+ # The following should trigger GC and not cause any problems
Karsten Hopp 9f9890
+ del i
Karsten Hopp 9f9890
+ del i2
Karsten Hopp 9f9890
+ i3 = iter(vim.buffers)
Karsten Hopp 9f9890
+ cb.append('i3:' + str(next(i3)))
Karsten Hopp 9f9890
+ del i3
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ prevnum = 0
Karsten Hopp 9f9890
+ for b in vim.buffers:
Karsten Hopp 9f9890
+     # Check buffer order
Karsten Hopp 9f9890
+     if prevnum >= b.number:
Karsten Hopp 9f9890
+         cb.append('!!! Buffer numbers not in strictly ascending order')
Karsten Hopp 9f9890
+     # Check indexing: vim.buffers[number].number == number
Karsten Hopp 9f9890
+     cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
Karsten Hopp 9f9890
+     prevnum = b.number
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ cb.append(str(len(vim.buffers)))
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ bnums = list(map(lambda b: b.number, vim.buffers))[1:]
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ # Test wiping out buffer with existing iterator
Karsten Hopp 9f9890
+ i4 = iter(vim.buffers)
Karsten Hopp 9f9890
+ cb.append('i4:' + str(next(i4)))
Karsten Hopp 9f9890
+ vim.command('bwipeout! ' + str(bnums.pop(0)))
Karsten Hopp 9f9890
+ try:
Karsten Hopp 9f9890
+     next(i4)
Karsten Hopp 9f9890
+ except vim.error:
Karsten Hopp 9f9890
+     pass
Karsten Hopp 9f9890
+ else:
Karsten Hopp 9f9890
+     cb.append('!!!! No vim.error')
Karsten Hopp 9f9890
+ i4 = iter(vim.buffers)
Karsten Hopp 9f9890
+ vim.command('bwipeout! ' + str(bnums.pop(-1)))
Karsten Hopp 9f9890
+ vim.command('bwipeout! ' + str(bnums.pop(-1)))
Karsten Hopp 9f9890
+ cb.append('i4:' + str(next(i4)))
Karsten Hopp 9f9890
+ try:
Karsten Hopp 9f9890
+     next(i4)
Karsten Hopp 9f9890
+ except StopIteration:
Karsten Hopp 9f9890
+     cb.append('StopIteration')
Karsten Hopp 9f9890
+ EOF
Karsten Hopp 9f9890
  :endfun
Karsten Hopp 9f9890
  :"
Karsten Hopp 9f9890
  :call Test()
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/testdir/test86.ok	2013-05-15 13:38:41.000000000 +0200
Karsten Hopp 9f9890
--- src/testdir/test86.ok	2013-05-15 14:27:21.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 319,321 ****
Karsten Hopp 9f9890
--- 319,333 ----
Karsten Hopp 9f9890
  Second line
Karsten Hopp 9f9890
  Third line
Karsten Hopp 9f9890
  foo
Karsten Hopp 9f9890
+ i:<buffer test86.in>
Karsten Hopp 9f9890
+ i2:<buffer test86.in>
Karsten Hopp 9f9890
+ i:<buffer a>
Karsten Hopp 9f9890
+ i3:<buffer test86.in>
Karsten Hopp 9f9890
+ 1:<buffer test86.in>=<buffer test86.in>
Karsten Hopp 9f9890
+ 6:<buffer a>=<buffer a>
Karsten Hopp 9f9890
+ 7:<buffer b>=<buffer b>
Karsten Hopp 9f9890
+ 8:<buffer c>=<buffer c>
Karsten Hopp 9f9890
+ 4
Karsten Hopp 9f9890
+ i4:<buffer test86.in>
Karsten Hopp 9f9890
+ i4:<buffer test86.in>
Karsten Hopp 9f9890
+ StopIteration
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/testdir/test87.in	2013-05-12 21:16:17.000000000 +0200
Karsten Hopp 9f9890
--- src/testdir/test87.in	2013-05-15 14:27:21.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 446,451 ****
Karsten Hopp 9f9890
--- 446,454 ----
Karsten Hopp 9f9890
  :   call RecVars(oname)
Karsten Hopp 9f9890
  :endfor
Karsten Hopp 9f9890
  :only
Karsten Hopp 9f9890
+ :for buf in g:bufs[1:]
Karsten Hopp 9f9890
+ :   execute 'bwipeout!' buf
Karsten Hopp 9f9890
+ :endfor
Karsten Hopp 9f9890
  :"
Karsten Hopp 9f9890
  :" Test buffer object
Karsten Hopp 9f9890
  :vnew
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 488,493 ****
Karsten Hopp 9f9890
--- 491,552 ----
Karsten Hopp 9f9890
          # Should not happen in any case
Karsten Hopp 9f9890
          cb.append('No exception for ' + expr)
Karsten Hopp 9f9890
  EOF
Karsten Hopp 9f9890
+ :"
Karsten Hopp 9f9890
+ :" Test vim.buffers object
Karsten Hopp 9f9890
+ :set hidden
Karsten Hopp 9f9890
+ :edit a
Karsten Hopp 9f9890
+ :buffer #
Karsten Hopp 9f9890
+ :edit b
Karsten Hopp 9f9890
+ :buffer #
Karsten Hopp 9f9890
+ :edit c
Karsten Hopp 9f9890
+ :buffer #
Karsten Hopp 9f9890
+ py3 << EOF
Karsten Hopp 9f9890
+ # Check GCing iterator that was not fully exhausted
Karsten Hopp 9f9890
+ i = iter(vim.buffers)
Karsten Hopp 9f9890
+ cb.append('i:' + str(next(i)))
Karsten Hopp 9f9890
+ # and also check creating more then one iterator at a time
Karsten Hopp 9f9890
+ i2 = iter(vim.buffers)
Karsten Hopp 9f9890
+ cb.append('i2:' + str(next(i2)))
Karsten Hopp 9f9890
+ cb.append('i:' + str(next(i)))
Karsten Hopp 9f9890
+ # The following should trigger GC and not cause any problems
Karsten Hopp 9f9890
+ del i
Karsten Hopp 9f9890
+ del i2
Karsten Hopp 9f9890
+ i3 = iter(vim.buffers)
Karsten Hopp 9f9890
+ cb.append('i3:' + str(next(i3)))
Karsten Hopp 9f9890
+ del i3
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ prevnum = 0
Karsten Hopp 9f9890
+ for b in vim.buffers:
Karsten Hopp 9f9890
+     # Check buffer order
Karsten Hopp 9f9890
+     if prevnum >= b.number:
Karsten Hopp 9f9890
+         cb.append('!!! Buffer numbers not in strictly ascending order')
Karsten Hopp 9f9890
+     # Check indexing: vim.buffers[number].number == number
Karsten Hopp 9f9890
+     cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
Karsten Hopp 9f9890
+     prevnum = b.number
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ cb.append(str(len(vim.buffers)))
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ bnums = list(map(lambda b: b.number, vim.buffers))[1:]
Karsten Hopp 9f9890
+ 
Karsten Hopp 9f9890
+ # Test wiping out buffer with existing iterator
Karsten Hopp 9f9890
+ i4 = iter(vim.buffers)
Karsten Hopp 9f9890
+ cb.append('i4:' + str(next(i4)))
Karsten Hopp 9f9890
+ vim.command('bwipeout! ' + str(bnums.pop(0)))
Karsten Hopp 9f9890
+ try:
Karsten Hopp 9f9890
+     next(i4)
Karsten Hopp 9f9890
+ except vim.error:
Karsten Hopp 9f9890
+     pass
Karsten Hopp 9f9890
+ else:
Karsten Hopp 9f9890
+     cb.append('!!!! No vim.error')
Karsten Hopp 9f9890
+ i4 = iter(vim.buffers)
Karsten Hopp 9f9890
+ vim.command('bwipeout! ' + str(bnums.pop(-1)))
Karsten Hopp 9f9890
+ vim.command('bwipeout! ' + str(bnums.pop(-1)))
Karsten Hopp 9f9890
+ cb.append('i4:' + str(next(i4)))
Karsten Hopp 9f9890
+ try:
Karsten Hopp 9f9890
+     next(i4)
Karsten Hopp 9f9890
+ except StopIteration:
Karsten Hopp 9f9890
+     cb.append('StopIteration')
Karsten Hopp 9f9890
+ EOF
Karsten Hopp 9f9890
  :endfun
Karsten Hopp 9f9890
  :"
Karsten Hopp 9f9890
  :call Test()
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 496,501 ****
Karsten Hopp 9f9890
--- 555,561 ----
Karsten Hopp 9f9890
  :call garbagecollect(1)
Karsten Hopp 9f9890
  :"
Karsten Hopp 9f9890
  :/^start:/,$wq! test.out
Karsten Hopp 9f9890
+ :call getchar()
Karsten Hopp 9f9890
  ENDTEST
Karsten Hopp 9f9890
  
Karsten Hopp 9f9890
  start:
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/testdir/test87.ok	2013-05-15 13:38:41.000000000 +0200
Karsten Hopp 9f9890
--- src/testdir/test87.ok	2013-05-15 14:27:21.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 308,310 ****
Karsten Hopp 9f9890
--- 308,322 ----
Karsten Hopp 9f9890
  Second line
Karsten Hopp 9f9890
  Third line
Karsten Hopp 9f9890
  foo
Karsten Hopp 9f9890
+ i:<buffer test87.in>
Karsten Hopp 9f9890
+ i2:<buffer test87.in>
Karsten Hopp 9f9890
+ i:<buffer a>
Karsten Hopp 9f9890
+ i3:<buffer test87.in>
Karsten Hopp 9f9890
+ 1:<buffer test87.in>=<buffer test87.in>
Karsten Hopp 9f9890
+ 6:<buffer a>=<buffer a>
Karsten Hopp 9f9890
+ 7:<buffer b>=<buffer b>
Karsten Hopp 9f9890
+ 8:<buffer c>=<buffer c>
Karsten Hopp 9f9890
+ 4
Karsten Hopp 9f9890
+ i4:<buffer test87.in>
Karsten Hopp 9f9890
+ i4:<buffer test87.in>
Karsten Hopp 9f9890
+ StopIteration
Karsten Hopp 9f9890
*** ../vim-7.3.946/src/version.c	2013-05-15 14:22:36.000000000 +0200
Karsten Hopp 9f9890
--- src/version.c	2013-05-15 14:25:26.000000000 +0200
Karsten Hopp 9f9890
***************
Karsten Hopp 9f9890
*** 730,731 ****
Karsten Hopp 9f9890
--- 730,733 ----
Karsten Hopp 9f9890
  {   /* Add new patch number below this line */
Karsten Hopp 9f9890
+ /**/
Karsten Hopp 9f9890
+     947,
Karsten Hopp 9f9890
  /**/
Karsten Hopp 9f9890
Karsten Hopp 9f9890
-- 
Karsten Hopp 9f9890
"It's so simple to be wise.  Just think of something stupid to say
Karsten Hopp 9f9890
and then don't say it."        -- Sam Levenson
Karsten Hopp 9f9890
Karsten Hopp 9f9890
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 9f9890
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 9f9890
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 9f9890
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///