diff --git a/7.3.941 b/7.3.941 new file mode 100644 index 0000000..c7792aa --- /dev/null +++ b/7.3.941 @@ -0,0 +1,1456 @@ +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 ///