To: vim_dev@googlegroups.com
Subject: Patch 7.3.941
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.941
Problem:    Stuff in if_py_both.h is ordered badly.
Solution:   Reorder by type. (ZyX)
Files:	    src/if_py_both.h, src/if_python.c


*** ../vim-7.3.940/src/if_py_both.h	2013-05-12 19:30:27.000000000 +0200
--- src/if_py_both.h	2013-05-12 19:36:38.000000000 +0200
***************
*** 7,13 ****
   * See README.txt for an overview of the Vim source code.
   */
  /*
!  * Python extensions by Paul Moore, David Leonard, Roland Puntaier.
   *
   * Common code for if_python.c and if_python3.c.
   */
--- 7,14 ----
   * See README.txt for an overview of the Vim source code.
   */
  /*
!  * Python extensions by Paul Moore, David Leonard, Roland Puntaier, Nikolay
!  * Pavlov.
   *
   * Common code for if_python.c and if_python3.c.
   */
***************
*** 22,27 ****
--- 23,39 ----
  # define ENC_OPT "latin1"
  #endif
  
+ #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
+ 
+ #define INVALID_BUFFER_VALUE ((buf_T *)(-1))
+ #define INVALID_WINDOW_VALUE ((win_T *)(-1))
+ 
+ static int ConvertFromPyObject(PyObject *, typval_T *);
+ static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
+ 
+ static PyInt RangeStart;
+ static PyInt RangeEnd;
+ 
  /*
   * obtain a lock on the Vim data structures
   */
***************
*** 38,53 ****
  {
  }
  
! /* Output object definition
   */
  
- static PyObject *OutputWrite(PyObject *, PyObject *);
- static PyObject *OutputWritelines(PyObject *, PyObject *);
- static PyObject *OutputFlush(PyObject *, PyObject *);
- 
  /* Function to write a line, points to either msg() or emsg(). */
  typedef void (*writefn)(char_u *);
! static void writer(writefn fn, char_u *str, PyInt n);
  
  typedef struct
  {
--- 50,62 ----
  {
  }
  
! /* Output buffer management
   */
  
  /* Function to write a line, points to either msg() or emsg(). */
  typedef void (*writefn)(char_u *);
! 
! static PyTypeObject OutputType;
  
  typedef struct
  {
***************
*** 56,76 ****
      long error;
  } OutputObject;
  
- static struct PyMethodDef OutputMethods[] = {
-     /* name,	    function,		calling,    documentation */
-     {"write",	    OutputWrite,	1,	    ""},
-     {"writelines",  OutputWritelines,	1,	    ""},
-     {"flush",	    OutputFlush,	1,	    ""},
-     { NULL,	    NULL,		0,	    NULL}
- };
- 
- #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
- 
- /*************/
- 
- /* Output buffer management
-  */
- 
      static int
  OutputSetattr(PyObject *self, char *name, PyObject *val)
  {
--- 65,70 ----
***************
*** 96,101 ****
--- 90,145 ----
      return -1;
  }
  
+ /* Buffer IO, we write one whole line at a time. */
+ static garray_T io_ga = {0, 0, 1, 80, NULL};
+ static writefn old_fn = NULL;
+ 
+     static void
+ PythonIO_Flush(void)
+ {
+     if (old_fn != NULL && io_ga.ga_len > 0)
+     {
+ 	((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
+ 	old_fn((char_u *)io_ga.ga_data);
+     }
+     io_ga.ga_len = 0;
+ }
+ 
+     static void
+ writer(writefn fn, char_u *str, PyInt n)
+ {
+     char_u *ptr;
+ 
+     /* Flush when switching output function. */
+     if (fn != old_fn)
+ 	PythonIO_Flush();
+     old_fn = fn;
+ 
+     /* Write each NL separated line.  Text after the last NL is kept for
+      * writing later. */
+     while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
+     {
+ 	PyInt len = ptr - str;
+ 
+ 	if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
+ 	    break;
+ 
+ 	mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
+ 	((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
+ 	fn((char_u *)io_ga.ga_data);
+ 	str = ptr + 1;
+ 	n -= len + 1;
+ 	io_ga.ga_len = 0;
+     }
+ 
+     /* Put the remaining text into io_ga for later printing. */
+     if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
+     {
+ 	mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
+ 	io_ga.ga_len += (int)n;
+     }
+ }
+ 
      static PyObject *
  OutputWrite(PyObject *self, PyObject *args)
  {
***************
*** 172,231 ****
      return Py_None;
  }
  
- 
- /* Buffer IO, we write one whole line at a time. */
- static garray_T io_ga = {0, 0, 1, 80, NULL};
- static writefn old_fn = NULL;
- 
-     static void
- PythonIO_Flush(void)
- {
-     if (old_fn != NULL && io_ga.ga_len > 0)
-     {
- 	((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
- 	old_fn((char_u *)io_ga.ga_data);
-     }
-     io_ga.ga_len = 0;
- }
- 
-     static void
- writer(writefn fn, char_u *str, PyInt n)
- {
-     char_u *ptr;
- 
-     /* Flush when switching output function. */
-     if (fn != old_fn)
- 	PythonIO_Flush();
-     old_fn = fn;
- 
-     /* Write each NL separated line.  Text after the last NL is kept for
-      * writing later. */
-     while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
-     {
- 	PyInt len = ptr - str;
- 
- 	if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
- 	    break;
- 
- 	mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
- 	((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
- 	fn((char_u *)io_ga.ga_data);
- 	str = ptr + 1;
- 	n -= len + 1;
- 	io_ga.ga_len = 0;
-     }
- 
-     /* Put the remaining text into io_ga for later printing. */
-     if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
-     {
- 	mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
- 	io_ga.ga_len += (int)n;
-     }
- }
- 
  /***************/
  
! static PyTypeObject OutputType;
  
  static OutputObject Output =
  {
--- 216,230 ----
      return Py_None;
  }
  
  /***************/
  
! static struct PyMethodDef OutputMethods[] = {
!     /* name,	    function,		calling,    documentation */
!     {"write",	    OutputWrite,	1,	    ""},
!     {"writelines",  OutputWritelines,	1,	    ""},
!     {"flush",	    OutputFlush,	1,	    ""},
!     { NULL,	    NULL,		0,	    NULL}
! };
  
  static OutputObject Output =
  {
***************
*** 281,286 ****
--- 280,286 ----
  
  /* Vim module - Implementation
   */
+ 
      static PyObject *
  VimCommand(PyObject *self UNUSED, PyObject *args)
  {
***************
*** 530,555 ****
      { NULL,	     NULL,		0,	    NULL }
  };
  
- typedef struct
- {
-     PyObject_HEAD
-     buf_T *buf;
- } BufferObject;
- 
- #define INVALID_BUFFER_VALUE ((buf_T *)(-1))
- 
  /*
   * Buffer list object - Implementation
   */
  
  typedef struct
  {
      PyObject_HEAD
  } BufListObject;
  
- static PyTypeObject BufListType;
- static PySequenceMethods WinListAsSeq;
- 
      static PyInt
  BufListLength(PyObject *self UNUSED)
  {
--- 530,547 ----
      { NULL,	     NULL,		0,	    NULL }
  };
  
  /*
   * Buffer list object - Implementation
   */
  
+ static PyTypeObject BufListType;
+ static PySequenceMethods BufListAsSeq;
+ 
  typedef struct
  {
      PyObject_HEAD
  } BufListObject;
  
      static PyInt
  BufListLength(PyObject *self UNUSED)
  {
***************
*** 580,599 ****
      return NULL;
  }
  
- typedef struct
- {
-     PyObject_HEAD
-     win_T	*win;
- } WindowObject;
- 
- static struct PyMethodDef WindowMethods[] = {
-     /* name,	    function,		calling,    documentation */
-     { NULL,	    NULL,		0,	    NULL }
- };
- 
- static int ConvertFromPyObject(PyObject *, typval_T *);
- static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
- 
  typedef struct pylinkedlist_S {
      struct pylinkedlist_S	*pll_next;
      struct pylinkedlist_S	*pll_prev;
--- 572,577 ----
***************
*** 655,670 ****
      pylinkedlist_T	ref;
  } DictionaryObject;
  
- static PyInt DictionaryAssItem(PyObject *, PyObject *, PyObject *);
- static PyInt DictionaryLength(PyObject *);
- static PyObject *DictionaryItem(PyObject *, PyObject *);
- 
- static PyMappingMethods DictionaryAsMapping = {
-     (lenfunc)       DictionaryLength,
-     (binaryfunc)    DictionaryItem,
-     (objobjargproc) DictionaryAssItem,
- };
- 
      static PyObject *
  DictionaryNew(dict_T *dict)
  {
--- 633,638 ----
***************
*** 693,895 ****
  }
  
      static int
! pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
  {
!     dict_T	*d;
!     char_u	*key;
!     dictitem_T	*di;
!     PyObject	*keyObject;
!     PyObject	*valObject;
!     Py_ssize_t	iter = 0;
  
!     d = dict_alloc();
!     if (d == NULL)
      {
! 	PyErr_NoMemory();
  	return -1;
      }
  
!     tv->v_type = VAR_DICT;
!     tv->vval.v_dict = d;
! 
!     while (PyDict_Next(obj, &iter, &keyObject, &valObject))
      {
! 	DICTKEY_DECL
! 
! 	if (keyObject == NULL)
! 	    return -1;
! 	if (valObject == NULL)
! 	    return -1;
! 
! 	DICTKEY_GET_NOTEMPTY(-1)
! 
! 	di = dictitem_alloc(key);
! 
! 	DICTKEY_UNREF
! 
! 	if (di == NULL)
! 	{
! 	    PyErr_NoMemory();
! 	    return -1;
! 	}
! 	di->di_tv.v_lock = 0;
! 
! 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
  	{
! 	    vim_free(di);
  	    return -1;
  	}
! 	if (dict_add(d, di) == FAIL)
  	{
! 	    vim_free(di);
! 	    PyErr_SetVim(_("failed to add key to dictionary"));
! 	    return -1;
  	}
      }
-     return 0;
  }
  
!     static int
! pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
  {
-     dict_T	*d;
      char_u	*key;
      dictitem_T	*di;
!     PyObject	*list;
!     PyObject	*litem;
!     PyObject	*keyObject;
!     PyObject	*valObject;
!     Py_ssize_t	lsize;
! 
!     d = dict_alloc();
!     if (d == NULL)
!     {
! 	PyErr_NoMemory();
! 	return -1;
!     }
! 
!     tv->v_type = VAR_DICT;
!     tv->vval.v_dict = d;
! 
!     list = PyMapping_Items(obj);
!     if (list == NULL)
! 	return -1;
!     lsize = PyList_Size(list);
!     while (lsize--)
!     {
! 	DICTKEY_DECL
! 
! 	litem = PyList_GetItem(list, lsize);
! 	if (litem == NULL)
! 	{
! 	    Py_DECREF(list);
! 	    return -1;
! 	}
! 
! 	keyObject = PyTuple_GetItem(litem, 0);
! 	if (keyObject == NULL)
! 	{
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    return -1;
! 	}
! 
! 	DICTKEY_GET_NOTEMPTY(-1)
! 
! 	valObject = PyTuple_GetItem(litem, 1);
! 	if (valObject == NULL)
! 	{
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    return -1;
! 	}
! 
! 	di = dictitem_alloc(key);
! 
! 	DICTKEY_UNREF
! 
! 	if (di == NULL)
! 	{
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    PyErr_NoMemory();
! 	    return -1;
! 	}
! 	di->di_tv.v_lock = 0;
! 
! 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
! 	{
! 	    vim_free(di);
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    return -1;
! 	}
! 	if (dict_add(d, di) == FAIL)
! 	{
! 	    vim_free(di);
! 	    Py_DECREF(list);
! 	    Py_DECREF(litem);
! 	    PyErr_SetVim(_("failed to add key to dictionary"));
! 	    return -1;
! 	}
! 	Py_DECREF(litem);
!     }
!     Py_DECREF(list);
!     return 0;
! }
! 
!     static int
! DictionarySetattr(PyObject *self, char *name, PyObject *val)
! {
!     DictionaryObject *this = (DictionaryObject *)(self);
! 
!     if (val == NULL)
!     {
! 	PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
! 	return -1;
!     }
! 
!     if (strcmp(name, "locked") == 0)
!     {
! 	if (this->dict->dv_lock == VAR_FIXED)
! 	{
! 	    PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary"));
! 	    return -1;
! 	}
! 	else
! 	{
! 	    if (!PyBool_Check(val))
! 	    {
! 		PyErr_SetString(PyExc_TypeError, _("Only boolean objects are allowed"));
! 		return -1;
! 	    }
! 
! 	    if (val == Py_True)
! 		this->dict->dv_lock = VAR_LOCKED;
! 	    else
! 		this->dict->dv_lock = 0;
! 	}
! 	return 0;
!     }
!     else
!     {
! 	PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
! 	return -1;
!     }
! }
! 
!     static PyInt
! DictionaryLength(PyObject *self)
! {
!     return ((PyInt) ((((DictionaryObject *)(self))->dict->dv_hashtab.ht_used)));
! }
! 
!     static PyObject *
! DictionaryItem(PyObject *self, PyObject *keyObject)
! {
!     char_u	*key;
!     dictitem_T	*di;
!     DICTKEY_DECL
  
      DICTKEY_GET_NOTEMPTY(NULL)
  
--- 661,717 ----
  }
  
      static int
! DictionarySetattr(PyObject *self, char *name, PyObject *val)
  {
!     DictionaryObject *this = (DictionaryObject *)(self);
  
!     if (val == NULL)
      {
! 	PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
  	return -1;
      }
  
!     if (strcmp(name, "locked") == 0)
      {
! 	if (this->dict->dv_lock == VAR_FIXED)
  	{
! 	    PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary"));
  	    return -1;
  	}
! 	else
  	{
! 	    if (!PyBool_Check(val))
! 	    {
! 		PyErr_SetString(PyExc_TypeError, _("Only boolean objects are allowed"));
! 		return -1;
! 	    }
! 
! 	    if (val == Py_True)
! 		this->dict->dv_lock = VAR_LOCKED;
! 	    else
! 		this->dict->dv_lock = 0;
  	}
+ 	return 0;
+     }
+     else
+     {
+ 	PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
+ 	return -1;
      }
  }
  
!     static PyInt
! DictionaryLength(PyObject *self)
! {
!     return ((PyInt) ((((DictionaryObject *)(self))->dict->dv_hashtab.ht_used)));
! }
! 
!     static PyObject *
! DictionaryItem(PyObject *self, PyObject *keyObject)
  {
      char_u	*key;
      dictitem_T	*di;
!     DICTKEY_DECL
  
      DICTKEY_GET_NOTEMPTY(NULL)
  
***************
*** 993,998 ****
--- 815,826 ----
      return r;
  }
  
+ static PyMappingMethods DictionaryAsMapping = {
+     (lenfunc)       DictionaryLength,
+     (binaryfunc)    DictionaryItem,
+     (objobjargproc) DictionaryAssItem,
+ };
+ 
  static struct PyMethodDef DictionaryMethods[] = {
      {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
      { NULL,	    NULL,		0,	    NULL }
***************
*** 1065,1136 ****
      return 0;
  }
  
-     static int
- pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
- {
-     list_T	*l;
- 
-     l = list_alloc();
-     if (l == NULL)
-     {
- 	PyErr_NoMemory();
- 	return -1;
-     }
- 
-     tv->v_type = VAR_LIST;
-     tv->vval.v_list = l;
- 
-     if (list_py_concat(l, obj, lookupDict) == -1)
- 	return -1;
- 
-     return 0;
- }
- 
-     static int
- pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
- {
-     PyObject	*iterator = PyObject_GetIter(obj);
-     PyObject	*item;
-     list_T	*l;
-     listitem_T	*li;
- 
-     l = list_alloc();
- 
-     if (l == NULL)
-     {
- 	PyErr_NoMemory();
- 	return -1;
-     }
- 
-     tv->vval.v_list = l;
-     tv->v_type = VAR_LIST;
- 
- 
-     if (iterator == NULL)
- 	return -1;
- 
-     while ((item = PyIter_Next(obj)))
-     {
- 	li = listitem_alloc();
- 	if (li == NULL)
- 	{
- 	    PyErr_NoMemory();
- 	    return -1;
- 	}
- 	li->li_tv.v_lock = 0;
- 
- 	if (_ConvertFromPyObject(item, &li->li_tv, lookupDict) == -1)
- 	    return -1;
- 
- 	list_append(l, li);
- 
- 	Py_DECREF(item);
-     }
- 
-     Py_DECREF(iterator);
-     return 0;
- }
- 
      static PyInt
  ListLength(PyObject *self)
  {
--- 893,898 ----
***************
*** 1768,1774 ****
      (objobjargproc) OptionsAssItem,
  };
  
! #define INVALID_WINDOW_VALUE ((win_T *)(-1))
  
      static int
  CheckWindow(WindowObject *this)
--- 1530,1547 ----
      (objobjargproc) OptionsAssItem,
  };
  
! /* Window object
!  */
! 
! typedef struct
! {
!     PyObject_HEAD
!     win_T	*win;
! } WindowObject;
! 
! static int WindowSetattr(PyObject *, char *, PyObject *);
! static PyObject *WindowRepr(PyObject *);
! static PyTypeObject WindowType;
  
      static int
  CheckWindow(WindowObject *this)
***************
*** 1782,1794 ****
      return 0;
  }
  
- /* Window object
-  */
- 
- static int WindowSetattr(PyObject *, char *, PyObject *);
- static PyObject *WindowRepr(PyObject *);
- static PyTypeObject WindowType;
- 
      static PyObject *
  WindowNew(win_T *win)
  {
--- 1555,1560 ----
***************
*** 1803,1809 ****
       * 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.
       */
  
--- 1569,1575 ----
       * 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.
       */
  
***************
*** 1826,1831 ****
--- 1592,1608 ----
      return (PyObject *)(self);
  }
  
+     static void
+ WindowDestructor(PyObject *self)
+ {
+     WindowObject *this = (WindowObject *)(self);
+ 
+     if (this->win && this->win != INVALID_WINDOW_VALUE)
+ 	WIN_PYTHON_REF(this->win) = NULL;
+ 
+     DESTRUCTOR_FINISH(self);
+ }
+ 
      static PyObject *
  WindowAttr(WindowObject *this, char *name)
  {
***************
*** 1863,1879 ****
  	return NULL;
  }
  
-     static void
- WindowDestructor(PyObject *self)
- {
-     WindowObject *this = (WindowObject *)(self);
- 
-     if (this->win && this->win != INVALID_WINDOW_VALUE)
- 	WIN_PYTHON_REF(this->win) = NULL;
- 
-     DESTRUCTOR_FINISH(self);
- }
- 
      static int
  WindowSetattr(PyObject *self, char *name, PyObject *val)
  {
--- 1640,1645 ----
***************
*** 1994,2011 ****
      }
  }
  
  /*
!  * Window list object - Implementation
   */
  
  typedef struct
  {
      PyObject_HEAD
  } WinListObject;
  
- static PyTypeObject WinListType;
- static PySequenceMethods BufListAsSeq;
- 
      static PyInt
  WinListLength(PyObject *self UNUSED)
  {
--- 1760,1782 ----
      }
  }
  
+ static struct PyMethodDef WindowMethods[] = {
+     /* name,	    function,		calling,    documentation */
+     { NULL,	    NULL,		0,	    NULL }
+ };
+ 
  /*
!  * Window list object
   */
  
+ static PyTypeObject WinListType;
+ static PySequenceMethods WinListAsSeq;
+ 
  typedef struct
  {
      PyObject_HEAD
  } WinListObject;
  
      static PyInt
  WinListLength(PyObject *self UNUSED)
  {
***************
*** 2596,2602 ****
   * -------------------------------------------
   */
  
!     static int
  CheckBuffer(BufferObject *this)
  {
      if (this->buf == INVALID_BUFFER_VALUE)
--- 2367,2379 ----
   * -------------------------------------------
   */
  
! typedef struct
! {
!     PyObject_HEAD
!     buf_T *buf;
! } BufferObject;
! 
!     static int
  CheckBuffer(BufferObject *this)
  {
      if (this->buf == INVALID_BUFFER_VALUE)
***************
*** 2737,2746 ****
      return Py_None;
  }
  
! /* Range object - Definitions
   */
  
  static PyTypeObject RangeType;
  
  typedef struct
  {
--- 2514,2525 ----
      return Py_None;
  }
  
! /* Range object
   */
  
  static PyTypeObject RangeType;
+ static PySequenceMethods RangeAsSeq;
+ static PyMappingMethods RangeAsMapping;
  
  typedef struct
  {
***************
*** 2750,2759 ****
      PyInt end;
  } RangeObject;
  
- static void RangeDestructor(PyObject *);
- static PySequenceMethods RangeAsSeq;
- static PyMappingMethods RangeAsMapping;
- 
      static PyObject *
  RangeNew(buf_T *buf, PyInt start, PyInt end)
  {
--- 2529,2534 ----
***************
*** 2785,2806 ****
      DESTRUCTOR_FINISH(self);
  }
  
! static PyTypeObject BufferType;
! static PyObject *BufferRepr(PyObject *);
! static PySequenceMethods BufferAsSeq;
! static PyMappingMethods BufferAsMapping;
  
!     static void
! BufferDestructor(PyObject *self)
  {
!     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)
  {
--- 2560,2642 ----
      DESTRUCTOR_FINISH(self);
  }
  
!     static PyInt
! RangeLength(PyObject *self)
! {
!     /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
!     if (CheckBuffer(((RangeObject *)(self))->buf))
! 	return -1; /* ??? */
  
!     return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
! }
! 
!     static PyObject *
! RangeItem(PyObject *self, PyInt n)
  {
!     return RBItem(((RangeObject *)(self))->buf, n,
! 		  ((RangeObject *)(self))->start,
! 		  ((RangeObject *)(self))->end);
! }
  
!     static PyObject *
! RangeSlice(PyObject *self, PyInt lo, PyInt hi)
! {
!     return RBSlice(((RangeObject *)(self))->buf, lo, hi,
! 		   ((RangeObject *)(self))->start,
! 		   ((RangeObject *)(self))->end);
! }
  
!     static PyObject *
! RangeAppend(PyObject *self, PyObject *args)
! {
!     return RBAppend(((RangeObject *)(self))->buf, args,
! 		    ((RangeObject *)(self))->start,
! 		    ((RangeObject *)(self))->end,
! 		    &((RangeObject *)(self))->end);
! }
! 
!     static PyObject *
! RangeRepr(PyObject *self)
! {
!     static char repr[100];
!     RangeObject *this = (RangeObject *)(self);
! 
!     if (this->buf->buf == INVALID_BUFFER_VALUE)
!     {
! 	vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
! 								      (self));
! 	return PyString_FromString(repr);
!     }
!     else
!     {
! 	char *name = (char *)this->buf->buf->b_fname;
! 	int len;
! 
! 	if (name == NULL)
! 	    name = "";
! 	len = (int)strlen(name);
! 
! 	if (len > 45)
! 	    name = name + (45 - len);
! 
! 	vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
! 		len > 45 ? "..." : "", name,
! 		this->start, this->end);
! 
! 	return PyString_FromString(repr);
!     }
  }
  
+ static struct PyMethodDef RangeMethods[] = {
+     /* name,	    function,		calling,    documentation */
+     {"append",	    RangeAppend,	1,	    "Append data to the Vim range" },
+     { NULL,	    NULL,		0,	    NULL }
+ };
+ 
+ static PyTypeObject BufferType;
+ static PySequenceMethods BufferAsSeq;
+ static PyMappingMethods BufferAsMapping;
+ 
      static PyObject *
  BufferNew(buf_T *buf)
  {
***************
*** 2817,2823 ****
       * 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.
       */
  
--- 2653,2659 ----
       * 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.
       */
  
***************
*** 2840,2861 ****
      return (PyObject *)(self);
  }
  
!     static PyObject *
! BufferAttr(BufferObject *this, char *name)
  {
!     if (strcmp(name, "name") == 0)
! 	return Py_BuildValue("s", this->buf->b_ffname);
!     else if (strcmp(name, "number") == 0)
! 	return Py_BuildValue(Py_ssize_t_fmt, this->buf->b_fnum);
!     else if (strcmp(name, "vars") == 0)
! 	return DictionaryNew(this->buf->b_vars);
!     else if (strcmp(name, "options") == 0)
! 	return OptionsNew(SREQ_BUF, this->buf, (checkfun) CheckBuffer,
! 			(PyObject *) this);
!     else if (strcmp(name,"__members__") == 0)
! 	return Py_BuildValue("[ssss]", "name", "number", "vars", "options");
!     else
! 	return NULL;
  }
  
      static PyInt
--- 2676,2690 ----
      return (PyObject *)(self);
  }
  
!     static void
! BufferDestructor(PyObject *self)
  {
!     BufferObject *this = (BufferObject *)(self);
! 
!     if (this->buf && this->buf != INVALID_BUFFER_VALUE)
! 	BUF_PYTHON_REF(this->buf) = NULL;
! 
!     DESTRUCTOR_FINISH(self);
  }
  
      static PyInt
***************
*** 2883,2888 ****
--- 2712,2735 ----
  }
  
      static PyObject *
+ BufferAttr(BufferObject *this, char *name)
+ {
+     if (strcmp(name, "name") == 0)
+ 	return Py_BuildValue("s", this->buf->b_ffname);
+     else if (strcmp(name, "number") == 0)
+ 	return Py_BuildValue(Py_ssize_t_fmt, this->buf->b_fnum);
+     else if (strcmp(name, "vars") == 0)
+ 	return DictionaryNew(this->buf->b_vars);
+     else if (strcmp(name, "options") == 0)
+ 	return OptionsNew(SREQ_BUF, this->buf, (checkfun) CheckBuffer,
+ 			(PyObject *) this);
+     else if (strcmp(name,"__members__") == 0)
+ 	return Py_BuildValue("[ssss]", "name", "number", "vars", "options");
+     else
+ 	return NULL;
+ }
+ 
+     static PyObject *
  BufferAppend(PyObject *self, PyObject *args)
  {
      return RBAppend((BufferObject *)(self), args, 1,
***************
*** 2985,3073 ****
      { NULL,	    NULL,		0,	    NULL }
  };
  
!     static PyObject *
! RangeAppend(PyObject *self, PyObject *args)
! {
!     return RBAppend(((RangeObject *)(self))->buf, args,
! 		    ((RangeObject *)(self))->start,
! 		    ((RangeObject *)(self))->end,
! 		    &((RangeObject *)(self))->end);
! }
! 
!     static PyInt
! RangeLength(PyObject *self)
! {
!     /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
!     if (CheckBuffer(((RangeObject *)(self))->buf))
! 	return -1; /* ??? */
! 
!     return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
! }
! 
!     static PyObject *
! RangeItem(PyObject *self, PyInt n)
! {
!     return RBItem(((RangeObject *)(self))->buf, n,
! 		  ((RangeObject *)(self))->start,
! 		  ((RangeObject *)(self))->end);
! }
! 
!     static PyObject *
! RangeRepr(PyObject *self)
! {
!     static char repr[100];
!     RangeObject *this = (RangeObject *)(self);
! 
!     if (this->buf->buf == INVALID_BUFFER_VALUE)
!     {
! 	vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
! 								      (self));
! 	return PyString_FromString(repr);
!     }
!     else
!     {
! 	char *name = (char *)this->buf->buf->b_fname;
! 	int len;
! 
! 	if (name == NULL)
! 	    name = "";
! 	len = (int)strlen(name);
! 
! 	if (len > 45)
! 	    name = name + (45 - len);
! 
! 	vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
! 		len > 45 ? "..." : "", name,
! 		this->start, this->end);
! 
! 	return PyString_FromString(repr);
!     }
! }
! 
!     static PyObject *
! RangeSlice(PyObject *self, PyInt lo, PyInt hi)
! {
!     return RBSlice(((RangeObject *)(self))->buf, lo, hi,
! 		   ((RangeObject *)(self))->start,
! 		   ((RangeObject *)(self))->end);
! }
! 
! /*
!  * Line range object - Definitions
!  */
! 
! static struct PyMethodDef RangeMethods[] = {
!     /* name,	    function,		calling,    documentation */
!     {"append",	    RangeAppend,	1,	    "Append data to the Vim range" },
!     { NULL,	    NULL,		0,	    NULL }
! };
! 
! /* Current items object - Implementation
   */
  
- static PyInt RangeStart;
- static PyInt RangeEnd;
- 
      static PyObject *
  CurrentGetattr(PyObject *self UNUSED, char *name)
  {
--- 2832,2840 ----
      { NULL,	    NULL,		0,	    NULL }
  };
  
! /* Current items object
   */
  
      static PyObject *
  CurrentGetattr(PyObject *self UNUSED, char *name)
  {
***************
*** 3147,3152 ****
--- 2914,3131 ----
      return 0;
  }
  
+     static int
+ pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
+ {
+     dict_T	*d;
+     char_u	*key;
+     dictitem_T	*di;
+     PyObject	*keyObject;
+     PyObject	*valObject;
+     Py_ssize_t	iter = 0;
+ 
+     d = dict_alloc();
+     if (d == NULL)
+     {
+ 	PyErr_NoMemory();
+ 	return -1;
+     }
+ 
+     tv->v_type = VAR_DICT;
+     tv->vval.v_dict = d;
+ 
+     while (PyDict_Next(obj, &iter, &keyObject, &valObject))
+     {
+ 	DICTKEY_DECL
+ 
+ 	if (keyObject == NULL)
+ 	    return -1;
+ 	if (valObject == NULL)
+ 	    return -1;
+ 
+ 	DICTKEY_GET_NOTEMPTY(-1)
+ 
+ 	di = dictitem_alloc(key);
+ 
+ 	DICTKEY_UNREF
+ 
+ 	if (di == NULL)
+ 	{
+ 	    PyErr_NoMemory();
+ 	    return -1;
+ 	}
+ 	di->di_tv.v_lock = 0;
+ 
+ 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
+ 	{
+ 	    vim_free(di);
+ 	    return -1;
+ 	}
+ 	if (dict_add(d, di) == FAIL)
+ 	{
+ 	    vim_free(di);
+ 	    PyErr_SetVim(_("failed to add key to dictionary"));
+ 	    return -1;
+ 	}
+     }
+     return 0;
+ }
+ 
+     static int
+ pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
+ {
+     dict_T	*d;
+     char_u	*key;
+     dictitem_T	*di;
+     PyObject	*list;
+     PyObject	*litem;
+     PyObject	*keyObject;
+     PyObject	*valObject;
+     Py_ssize_t	lsize;
+ 
+     d = dict_alloc();
+     if (d == NULL)
+     {
+ 	PyErr_NoMemory();
+ 	return -1;
+     }
+ 
+     tv->v_type = VAR_DICT;
+     tv->vval.v_dict = d;
+ 
+     list = PyMapping_Items(obj);
+     if (list == NULL)
+ 	return -1;
+     lsize = PyList_Size(list);
+     while (lsize--)
+     {
+ 	DICTKEY_DECL
+ 
+ 	litem = PyList_GetItem(list, lsize);
+ 	if (litem == NULL)
+ 	{
+ 	    Py_DECREF(list);
+ 	    return -1;
+ 	}
+ 
+ 	keyObject = PyTuple_GetItem(litem, 0);
+ 	if (keyObject == NULL)
+ 	{
+ 	    Py_DECREF(list);
+ 	    Py_DECREF(litem);
+ 	    return -1;
+ 	}
+ 
+ 	DICTKEY_GET_NOTEMPTY(-1)
+ 
+ 	valObject = PyTuple_GetItem(litem, 1);
+ 	if (valObject == NULL)
+ 	{
+ 	    Py_DECREF(list);
+ 	    Py_DECREF(litem);
+ 	    return -1;
+ 	}
+ 
+ 	di = dictitem_alloc(key);
+ 
+ 	DICTKEY_UNREF
+ 
+ 	if (di == NULL)
+ 	{
+ 	    Py_DECREF(list);
+ 	    Py_DECREF(litem);
+ 	    PyErr_NoMemory();
+ 	    return -1;
+ 	}
+ 	di->di_tv.v_lock = 0;
+ 
+ 	if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
+ 	{
+ 	    vim_free(di);
+ 	    Py_DECREF(list);
+ 	    Py_DECREF(litem);
+ 	    return -1;
+ 	}
+ 	if (dict_add(d, di) == FAIL)
+ 	{
+ 	    vim_free(di);
+ 	    Py_DECREF(list);
+ 	    Py_DECREF(litem);
+ 	    PyErr_SetVim(_("failed to add key to dictionary"));
+ 	    return -1;
+ 	}
+ 	Py_DECREF(litem);
+     }
+     Py_DECREF(list);
+     return 0;
+ }
+ 
+     static int
+ pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
+ {
+     list_T	*l;
+ 
+     l = list_alloc();
+     if (l == NULL)
+     {
+ 	PyErr_NoMemory();
+ 	return -1;
+     }
+ 
+     tv->v_type = VAR_LIST;
+     tv->vval.v_list = l;
+ 
+     if (list_py_concat(l, obj, lookupDict) == -1)
+ 	return -1;
+ 
+     return 0;
+ }
+ 
+     static int
+ pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
+ {
+     PyObject	*iterator = PyObject_GetIter(obj);
+     PyObject	*item;
+     list_T	*l;
+     listitem_T	*li;
+ 
+     l = list_alloc();
+ 
+     if (l == NULL)
+     {
+ 	PyErr_NoMemory();
+ 	return -1;
+     }
+ 
+     tv->vval.v_list = l;
+     tv->v_type = VAR_LIST;
+ 
+ 
+     if (iterator == NULL)
+ 	return -1;
+ 
+     while ((item = PyIter_Next(obj)))
+     {
+ 	li = listitem_alloc();
+ 	if (li == NULL)
+ 	{
+ 	    PyErr_NoMemory();
+ 	    return -1;
+ 	}
+ 	li->li_tv.v_lock = 0;
+ 
+ 	if (_ConvertFromPyObject(item, &li->li_tv, lookupDict) == -1)
+ 	    return -1;
+ 
+ 	list_append(l, li);
+ 
+ 	Py_DECREF(item);
+     }
+ 
+     Py_DECREF(iterator);
+     return 0;
+ }
+ 
  typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
  
      static int
*** ../vim-7.3.940/src/if_python.c	2013-05-12 18:44:44.000000000 +0200
--- src/if_python.c	2013-05-12 19:34:35.000000000 +0200
***************
*** 1019,1027 ****
  
  #define BufferType_Check(obj) ((obj)->ob_type == &BufferType)
  
- static PyInt BufferLength(PyObject *);
- static PyObject *BufferItem(PyObject *, PyInt);
- static PyObject *BufferSlice(PyObject *, PyInt, PyInt);
  static PyInt BufferAssItem(PyObject *, PyInt, PyObject *);
  static PyInt BufferAssSlice(PyObject *, PyInt, PyInt, PyObject *);
  
--- 1019,1024 ----
*** ../vim-7.3.940/src/version.c	2013-05-12 19:30:27.000000000 +0200
--- src/version.c	2013-05-12 19:37:08.000000000 +0200
***************
*** 730,731 ****
--- 730,733 ----
  {   /* Add new patch number below this line */
+ /**/
+     941,
  /**/

-- 
ARTHUR:  Well, I AM king...
DENNIS:  Oh king, eh, very nice.  An' how'd you get that, eh?  By exploitin'
         the workers -- by 'angin' on to outdated imperialist dogma which
         perpetuates the economic an' social differences in our society!  If
         there's ever going to be any progress--
                                  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    ///
