| 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 |
| |
| |
| |
| |
| |
| *** 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; |
| - } |
| - } |
| - |
| / |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| *** 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 |
| |
| |
| |
| *** 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 ---- |
| |
| |
| |
| *** 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 /// |