diff --git a/7.3.569 b/7.3.569 new file mode 100644 index 0000000..435733f --- /dev/null +++ b/7.3.569 @@ -0,0 +1,4762 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.3.569 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.3.569 +Problem: Evaluating Vim expression in Python is insufficient. +Solution: Add vim.bindeval(). Also add pyeval() and py3eval(). (ZyX) +Files: runtime/doc/eval.txt, runtime/doc/if_pyth.txt, src/eval.c, + src/if_lua.c, src/if_py_both.h, src/if_python.c, src/if_python3.c, + src/proto/eval.pro, src/proto/if_python.pro, + src/proto/if_python3.pro, src/testdir/Make_amiga.mak, + src/testdir/Make_dos.mak, src/testdir/Make_ming.mak, + src/testdir/Make_os2.mak, src/testdir/Makefile, + src/testdir/test86.in, src/testdir/test86.ok, + src/testdir/test87.in, src/testdir/test87.ok + + +*** ../vim-7.3.568/runtime/doc/eval.txt 2012-03-07 19:16:49.000000000 +0100 +--- runtime/doc/eval.txt 2012-06-20 18:01:02.000000000 +0200 +*************** +*** 1836,1844 **** + localtime() Number current time + log( {expr}) Float natural logarithm (base e) of {expr} + log10( {expr}) Float logarithm of Float {expr} to base 10 + map( {expr}, {string}) List/Dict change each item in {expr} to {expr} + maparg( {name}[, {mode} [, {abbr} [, {dict}]]]) +! String rhs of mapping {name} in mode {mode} + mapcheck( {name}[, {mode} [, {abbr}]]) + String check for mappings matching {name} + match( {expr}, {pat}[, {start}[, {count}]]) +--- 1847,1857 ---- + localtime() Number current time + log( {expr}) Float natural logarithm (base e) of {expr} + log10( {expr}) Float logarithm of Float {expr} to base 10 ++ luaeval( {expr}[, {expr}]) any evaluate |Lua| expression + map( {expr}, {string}) List/Dict change each item in {expr} to {expr} + maparg( {name}[, {mode} [, {abbr} [, {dict}]]]) +! String or Dict +! rhs of mapping {name} in mode {mode} + mapcheck( {name}[, {mode} [, {abbr}]]) + String check for mappings matching {name} + match( {expr}, {pat}[, {start}[, {count}]]) +*************** +*** 1867,1872 **** +--- 1880,1887 ---- + prevnonblank( {lnum}) Number line nr of non-blank line <= {lnum} + printf( {fmt}, {expr1}...) String format text + pumvisible() Number whether popup menu is visible ++ pyeval( {expr}) any evaluate |Python| expression ++ py3eval( {expr}) any evaluate |python3| expression + range( {expr} [, {max} [, {stride}]]) + List items from {expr} to {max} + readfile( {fname} [, {binary} [, {max}]]) +*************** +*** 3980,3985 **** +--- 4003,4022 ---- + < -2.0 + {only available when compiled with the |+float| feature} + ++ luaeval({expr}[, {expr}]) *luaeval()* ++ Evaluate Lua expression {expr} and return its result converted ++ to Vim data structures. Second {expr} may hold additional ++ argument accessible as _A inside first {expr}. ++ Strings are returned as they are. ++ Boolean objects are converted to numbers. ++ Numbers are converted to |Float| values if vim was compiled ++ with |+float| and to numbers otherwise. ++ Dictionaries and lists obtained by vim.eval() are returned ++ as-is. ++ Other objects are returned as zero without any errors. ++ See |lua-luaeval| for more details. ++ {only available when compiled with the |+lua| feature} ++ + map({expr}, {string}) *map()* + {expr} must be a |List| or a |Dictionary|. + Replace each item in {expr} with the result of evaluating +*************** +*** 4574,4579 **** +--- 4612,4640 ---- + This can be used to avoid some things that would remove the + popup menu. + ++ *E860* *E861* ++ py3eval({expr}) *py3eval()* ++ Evaluate Python expression {expr} and return its result ++ converted to Vim data structures. ++ Numbers and strings are returned as they are (strings are ++ copied though, unicode strings are additionally converted to ++ 'encoding'). ++ Lists are represented as Vim |List| type. ++ Dictionaries are represented as Vim |Dictionary| type with ++ keys converted to strings. ++ {only available when compiled with the |+python3| feature} ++ ++ *E858* *E859* ++ pyeval({expr}) *pyeval()* ++ Evaluate Python expression {expr} and return its result ++ converted to Vim data structures. ++ Numbers and strings are returned as they are (strings are ++ copied though). ++ Lists are represented as Vim |List| type. ++ Dictionaries are represented as Vim |Dictionary| type with ++ keys converted to strings. ++ {only available when compiled with the |+python| feature} ++ + *E726* *E727* + range({expr} [, {max} [, {stride}]]) *range()* + Returns a |List| with Numbers: +*************** +*** 4807,4812 **** +--- 4868,4877 ---- + Search for regexp pattern {pattern}. The search starts at the + cursor position (you can use |cursor()| to set it). + ++ If there is no match a 0 is returned and the cursor doesn't ++ move. No error message is given. ++ When a match has been found its line number is returned. ++ + {flags} is a String, which can contain these character flags: + 'b' search backward instead of forward + 'c' accept a match at the cursor position +*** ../vim-7.3.568/runtime/doc/if_pyth.txt 2010-08-15 21:57:12.000000000 +0200 +--- runtime/doc/if_pyth.txt 2012-06-20 18:01:02.000000000 +0200 +*************** +*** 1,4 **** +! *if_pyth.txt* For Vim version 7.3. Last change: 2010 Aug 13 + + + VIM REFERENCE MANUAL by Paul Moore +--- 1,4 ---- +! *if_pyth.txt* For Vim version 7.3. Last change: 2012 Feb 04 + + + VIM REFERENCE MANUAL by Paul Moore +*************** +*** 6,18 **** + + The Python Interface to Vim *python* *Python* + +! 1. Commands |python-commands| +! 2. The vim module |python-vim| +! 3. Buffer objects |python-buffer| +! 4. Range objects |python-range| +! 5. Window objects |python-window| +! 6. Dynamic loading |python-dynamic| +! 7. Python 3 |python3| + + {Vi does not have any of these commands} + +--- 6,19 ---- + + The Python Interface to Vim *python* *Python* + +! 1. Commands |python-commands| +! 2. The vim module |python-vim| +! 3. Buffer objects |python-buffer| +! 4. Range objects |python-range| +! 5. Window objects |python-window| +! 6. pyeval(), py3eval() Vim functions |python-pyeval| +! 7. Dynamic loading |python-dynamic| +! 8. Python 3 |python3| + + {Vi does not have any of these commands} + +*************** +*** 150,155 **** +--- 151,172 ---- + [{'cmd': '/^eval_expr(arg, nextcmd)$/', 'static': 0, 'name': + 'eval_expr', 'kind': 'f', 'filename': './src/eval.c'}] + ++ vim.bindeval(str) *python-bindeval* ++ Like |python-eval|, but ++ 1. if expression evaluates to |List| or |Dictionary| it is returned as ++ vimlist or vimdictionary python type that are connected to original ++ list or dictionary. Thus modifications to these objects imply ++ modifications of the original. ++ 2. if expression evaluates to a function reference, then it returns ++ callable vimfunction object. Use self keyword argument to assign ++ |self| object for dictionary functions. ++ ++ Note: this function has the same behavior as |lua-eval| (except that ++ lua does not support running vim functions), |python-eval| is ++ kept for backwards compatibility in order not to make scripts ++ relying on outputs of vim.eval() being a copy of original or ++ vim.eval("1") returning a string. ++ + + + Error object of the "vim" module +*************** +*** 222,229 **** + - from indexing vim.buffers (|python-buffers|) + - from the "buffer" attribute of a window (|python-window|) + +! Buffer objects have one read-only attribute - name - the full file name for +! the buffer. They also have three methods (append, mark, and range; see below). + + You can also treat buffer objects as sequence objects. In this context, they + act as if they were lists (yes, they are mutable) of strings, with each +--- 239,247 ---- + - from indexing vim.buffers (|python-buffers|) + - from the "buffer" attribute of a window (|python-window|) + +! Buffer objects have two read-only attributes - name - the full file name for +! the buffer, and number - the buffer number. They also have three methods +! (append, mark, and range; see below). + + You can also treat buffer objects as sequence objects. In this context, they + act as if they were lists (yes, they are mutable) of strings, with each +*************** +*** 318,324 **** + The width attribute is writable only if the screen is split vertically. + + ============================================================================== +! 6. Dynamic loading *python-dynamic* + + On MS-Windows the Python library can be loaded dynamically. The |:version| + output then includes |+python/dyn|. +--- 336,348 ---- + The width attribute is writable only if the screen is split vertically. + + ============================================================================== +! 6. pyeval() and py3eval() Vim functions *python-pyeval* +! +! To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()| +! functions to evaluate Python expressions and pass their values to VimL. +! +! ============================================================================== +! 7. Dynamic loading *python-dynamic* + + On MS-Windows the Python library can be loaded dynamically. The |:version| + output then includes |+python/dyn|. +*************** +*** 335,347 **** + sure edit "gvim.exe" and search for "python\d*.dll\c". + + ============================================================================== +! 7. Python 3 *python3* + + *:py3* *:python3* + The |:py3| and |:python3| commands work similar to |:python|. + *:py3file* + The |:py3file| command works similar to |:pyfile|. + + Vim can be built in four ways (:version output): + 1. No Python support (-python, -python3) + 2. Python 2 support only (+python or +python/dyn, -python3) +--- 359,372 ---- + sure edit "gvim.exe" and search for "python\d*.dll\c". + + ============================================================================== +! 8. Python 3 *python3* + + *:py3* *:python3* + The |:py3| and |:python3| commands work similar to |:python|. + *:py3file* + The |:py3file| command works similar to |:pyfile|. + ++ + Vim can be built in four ways (:version output): + 1. No Python support (-python, -python3) + 2. Python 2 support only (+python or +python/dyn, -python3) +*************** +*** 355,361 **** + When doing this on Linux/Unix systems and importing global symbols, this leads + to a crash when the second Python version is used. So either global symbols + are loaded but only one Python version is activated, or no global symbols are +! loaded. The latter makes Python's "import" fail on libaries that expect the + symbols to be provided by Vim. + *E836* *E837* + Vim's configuration script makes a guess for all libraries based on one +--- 380,386 ---- + When doing this on Linux/Unix systems and importing global symbols, this leads + to a crash when the second Python version is used. So either global symbols + are loaded but only one Python version is activated, or no global symbols are +! loaded. The latter makes Python's "import" fail on libraries that expect the + symbols to be provided by Vim. + *E836* *E837* + Vim's configuration script makes a guess for all libraries based on one +*************** +*** 377,382 **** +--- 402,419 ---- + 3. You undefine PY_NO_RTLD_GLOBAL in auto/config.h after configuration. This + may crash Vim though. + ++ *has-python* ++ You can test what Python version is available with: > ++ if has('python') ++ echo 'there is Python 2.x' ++ elseif has('python3') ++ echo 'there is Python 3.x' ++ endif ++ ++ Note however, that when Python 2 and 3 are both available and loaded ++ dynamically, these has() calls will try to load them. If only one can be ++ loaded at a time, just checking if Python 2 or 3 are available will prevent ++ the other one from being available. + + ============================================================================== + vim:tw=78:ts=8:ft=help:norl: +*** ../vim-7.3.568/src/eval.c 2012-06-20 14:13:02.000000000 +0200 +--- src/eval.c 2012-06-20 18:29:15.000000000 +0200 +*************** +*** 424,453 **** + static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); + static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); + static int rettv_list_alloc __ARGS((typval_T *rettv)); +- static listitem_T *listitem_alloc __ARGS((void)); + static void listitem_free __ARGS((listitem_T *item)); +- static void listitem_remove __ARGS((list_T *l, listitem_T *item)); + static long list_len __ARGS((list_T *l)); + static int list_equal __ARGS((list_T *l1, list_T *l2, int ic, int recursive)); + static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic, int recursive)); + static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic, int recursive)); +- static listitem_T *list_find __ARGS((list_T *l, long n)); + static long list_find_nr __ARGS((list_T *l, long idx, int *errorp)); + static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); +- static void list_append __ARGS((list_T *l, listitem_T *item)); + static int list_append_number __ARGS((list_T *l, varnumber_T n)); +- static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); + static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); + static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); + static list_T *list_copy __ARGS((list_T *orig, int deep, int copyID)); +- static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); + static char_u *list2string __ARGS((typval_T *tv, int copyID)); + static int list_join_inner __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo_style, int copyID, garray_T *join_gap)); + static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID)); + static int free_unref_items __ARGS((int copyID)); +- static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); +- static void set_ref_in_list __ARGS((list_T *l, int copyID)); +- static void set_ref_in_item __ARGS((typval_T *tv, int copyID)); + static int rettv_dict_alloc __ARGS((typval_T *rettv)); + static void dict_free __ARGS((dict_T *d, int recurse)); + static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); +--- 424,444 ---- +*************** +*** 654,659 **** +--- 645,656 ---- + static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_printf __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_pumvisible __ARGS((typval_T *argvars, typval_T *rettv)); ++ #ifdef FEAT_PYTHON3 ++ static void f_py3eval __ARGS((typval_T *argvars, typval_T *rettv)); ++ #endif ++ #ifdef FEAT_PYTHON ++ static void f_pyeval __ARGS((typval_T *argvars, typval_T *rettv)); ++ #endif + static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_reltime __ARGS((typval_T *argvars, typval_T *rettv)); +*************** +*** 824,831 **** + static char_u *autoload_name __ARGS((char_u *name)); + static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); + static void func_free __ARGS((ufunc_T *fp)); +- static void func_unref __ARGS((char_u *name)); +- static void func_ref __ARGS((char_u *name)); + static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict)); + static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ; + static void free_funccal __ARGS((funccall_T *fc, int free_val)); +--- 821,826 ---- +*************** +*** 5927,5933 **** + /* + * Allocate a list item. + */ +! static listitem_T * + listitem_alloc() + { + return (listitem_T *)alloc(sizeof(listitem_T)); +--- 5922,5928 ---- + /* + * Allocate a list item. + */ +! listitem_T * + listitem_alloc() + { + return (listitem_T *)alloc(sizeof(listitem_T)); +*************** +*** 5947,5953 **** + /* + * Remove a list item from a List and free it. Also clears the value. + */ +! static void + listitem_remove(l, item) + list_T *l; + listitem_T *item; +--- 5942,5948 ---- + /* + * Remove a list item from a List and free it. Also clears the value. + */ +! void + listitem_remove(l, item) + list_T *l; + listitem_T *item; +*************** +*** 6123,6129 **** + * A negative index is counted from the end; -1 is the last item. + * Returns NULL when "n" is out of range. + */ +! static listitem_T * + list_find(l, n) + list_T *l; + long n; +--- 6118,6124 ---- + * A negative index is counted from the end; -1 is the last item. + * Returns NULL when "n" is out of range. + */ +! listitem_T * + list_find(l, n) + list_T *l; + long n; +*************** +*** 6265,6271 **** + /* + * Append item "item" to the end of list "l". + */ +! static void + list_append(l, item) + list_T *l; + listitem_T *item; +--- 6260,6266 ---- + /* + * Append item "item" to the end of list "l". + */ +! void + list_append(l, item) + list_T *l; + listitem_T *item; +*************** +*** 6378,6384 **** + * If "item" is NULL append at the end. + * Return FAIL when out of memory. + */ +! static int + list_insert_tv(l, tv, item) + list_T *l; + typval_T *tv; +--- 6373,6379 ---- + * If "item" is NULL append at the end. + * Return FAIL when out of memory. + */ +! int + list_insert_tv(l, tv, item) + list_T *l; + typval_T *tv; +*************** +*** 6523,6529 **** + * Remove items "item" to "item2" from list "l". + * Does not free the listitem or the value! + */ +! static void + list_remove(l, item, item2) + list_T *l; + listitem_T *item; +--- 6518,6524 ---- + * Remove items "item" to "item2" from list "l". + * Does not free the listitem or the value! + */ +! void + list_remove(l, item, item2) + list_T *l; + listitem_T *item; +*************** +*** 6785,6790 **** +--- 6780,6793 ---- + set_ref_in_lua(copyID); + #endif + ++ #ifdef FEAT_PYTHON ++ set_ref_in_python(copyID); ++ #endif ++ ++ #ifdef FEAT_PYTHON3 ++ set_ref_in_python3(copyID); ++ #endif ++ + /* + * 2. Free lists and dictionaries that are not referenced. + */ +*************** +*** 6870,6876 **** + /* + * Mark all lists and dicts referenced through hashtab "ht" with "copyID". + */ +! static void + set_ref_in_ht(ht, copyID) + hashtab_T *ht; + int copyID; +--- 6873,6879 ---- + /* + * Mark all lists and dicts referenced through hashtab "ht" with "copyID". + */ +! void + set_ref_in_ht(ht, copyID) + hashtab_T *ht; + int copyID; +*************** +*** 6890,6896 **** + /* + * Mark all lists and dicts referenced through list "l" with "copyID". + */ +! static void + set_ref_in_list(l, copyID) + list_T *l; + int copyID; +--- 6893,6899 ---- + /* + * Mark all lists and dicts referenced through list "l" with "copyID". + */ +! void + set_ref_in_list(l, copyID) + list_T *l; + int copyID; +*************** +*** 6904,6910 **** + /* + * Mark all lists and dicts referenced through typval "tv" with "copyID". + */ +! static void + set_ref_in_item(tv, copyID) + typval_T *tv; + int copyID; +--- 6907,6913 ---- + /* + * Mark all lists and dicts referenced through typval "tv" with "copyID". + */ +! void + set_ref_in_item(tv, copyID) + typval_T *tv; + int copyID; +*************** +*** 7986,7991 **** +--- 7989,8000 ---- + {"prevnonblank", 1, 1, f_prevnonblank}, + {"printf", 2, 19, f_printf}, + {"pumvisible", 0, 0, f_pumvisible}, ++ #ifdef FEAT_PYTHON3 ++ {"py3eval", 1, 1, f_py3eval}, ++ #endif ++ #ifdef FEAT_PYTHON ++ {"pyeval", 1, 1, f_pyeval}, ++ #endif + {"range", 1, 3, f_range}, + {"readfile", 1, 3, f_readfile}, + {"reltime", 0, 2, f_reltime}, +*************** +*** 9150,9155 **** +--- 9159,9203 ---- + #endif + } + ++ int ++ func_call(name, args, selfdict, rettv) ++ char_u *name; ++ typval_T *args; ++ dict_T *selfdict; ++ typval_T *rettv; ++ { ++ listitem_T *item; ++ typval_T argv[MAX_FUNC_ARGS + 1]; ++ int argc = 0; ++ int dummy; ++ int r = 0; ++ ++ for (item = args->vval.v_list->lv_first; item != NULL; ++ item = item->li_next) ++ { ++ if (argc == MAX_FUNC_ARGS) ++ { ++ EMSG(_("E699: Too many arguments")); ++ break; ++ } ++ /* Make a copy of each argument. This is needed to be able to set ++ * v_lock to VAR_FIXED in the copy without changing the original list. ++ */ ++ copy_tv(&item->li_tv, &argv[argc++]); ++ } ++ ++ if (item == NULL) ++ r = call_func(name, (int)STRLEN(name), rettv, argc, argv, ++ curwin->w_cursor.lnum, curwin->w_cursor.lnum, ++ &dummy, TRUE, selfdict); ++ ++ /* Free the arguments. */ ++ while (argc > 0) ++ clear_tv(&argv[--argc]); ++ ++ return r; ++ } ++ + /* + * "call(func, arglist)" function + */ +*************** +*** 9159,9168 **** + typval_T *rettv; + { + char_u *func; +- typval_T argv[MAX_FUNC_ARGS + 1]; +- int argc = 0; +- listitem_T *item; +- int dummy; + dict_T *selfdict = NULL; + + if (argvars[1].v_type != VAR_LIST) +--- 9207,9212 ---- +*************** +*** 9190,9217 **** + selfdict = argvars[2].vval.v_dict; + } + +! for (item = argvars[1].vval.v_list->lv_first; item != NULL; +! item = item->li_next) +! { +! if (argc == MAX_FUNC_ARGS) +! { +! EMSG(_("E699: Too many arguments")); +! break; +! } +! /* Make a copy of each argument. This is needed to be able to set +! * v_lock to VAR_FIXED in the copy without changing the original list. +! */ +! copy_tv(&item->li_tv, &argv[argc++]); +! } +! +! if (item == NULL) +! (void)call_func(func, (int)STRLEN(func), rettv, argc, argv, +! curwin->w_cursor.lnum, curwin->w_cursor.lnum, +! &dummy, TRUE, selfdict); +! +! /* Free the arguments. */ +! while (argc > 0) +! clear_tv(&argv[--argc]); + } + + #ifdef FEAT_FLOAT +--- 9234,9240 ---- + selfdict = argvars[2].vval.v_dict; + } + +! (void)func_call(func, &argvars[1], selfdict, rettv); + } + + #ifdef FEAT_FLOAT +*************** +*** 14424,14429 **** +--- 14447,14486 ---- + #endif + } + ++ #ifdef FEAT_PYTHON3 ++ /* ++ * "py3eval()" function ++ */ ++ static void ++ f_py3eval(argvars, rettv) ++ typval_T *argvars; ++ typval_T *rettv; ++ { ++ char_u *str; ++ char_u buf[NUMBUFLEN]; ++ ++ str = get_tv_string_buf(&argvars[0], buf); ++ do_py3eval(str, rettv); ++ } ++ #endif ++ ++ #ifdef FEAT_PYTHON ++ /* ++ * "pyeval()" function ++ */ ++ static void ++ f_pyeval(argvars, rettv) ++ typval_T *argvars; ++ typval_T *rettv; ++ { ++ char_u *str; ++ char_u buf[NUMBUFLEN]; ++ ++ str = get_tv_string_buf(&argvars[0], buf); ++ do_pyeval(str, rettv); ++ } ++ #endif ++ + /* + * "range()" function + */ +*************** +*** 22139,22145 **** + * Unreference a Function: decrement the reference count and free it when it + * becomes zero. Only for numbered functions. + */ +! static void + func_unref(name) + char_u *name; + { +--- 22196,22202 ---- + * Unreference a Function: decrement the reference count and free it when it + * becomes zero. Only for numbered functions. + */ +! void + func_unref(name) + char_u *name; + { +*************** +*** 22163,22169 **** + /* + * Count a reference to a Function. + */ +! static void + func_ref(name) + char_u *name; + { +--- 22220,22226 ---- + /* + * Count a reference to a Function. + */ +! void + func_ref(name) + char_u *name; + { +*** ../vim-7.3.568/src/if_lua.c 2012-04-06 14:30:55.000000000 +0200 +--- src/if_lua.c 2012-06-20 18:16:33.000000000 +0200 +*************** +*** 199,207 **** + lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum); + lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum); + void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx, +! lua_CFunction k); + int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, +! int ctx, lua_CFunction k); + void (*dll_lua_getglobal) (lua_State *L, const char *var); + void (*dll_lua_setglobal) (lua_State *L, const char *var); + #endif +--- 199,207 ---- + lua_Number (*dll_lua_tonumberx) (lua_State *L, int idx, int *isnum); + lua_Integer (*dll_lua_tointegerx) (lua_State *L, int idx, int *isnum); + void (*dll_lua_callk) (lua_State *L, int nargs, int nresults, int ctx, +! lua_CFunction k); + int (*dll_lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, +! int ctx, lua_CFunction k); + void (*dll_lua_getglobal) (lua_State *L, const char *var); + void (*dll_lua_setglobal) (lua_State *L, const char *var); + #endif +*************** +*** 394,400 **** + luaL_typeerror (lua_State *L, int narg, const char *tname) + { + const char *msg = lua_pushfstring(L, "%s expected, got %s", +! tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); + } + #endif +--- 394,400 ---- + luaL_typeerror (lua_State *L, int narg, const char *tname) + { + const char *msg = lua_pushfstring(L, "%s expected, got %s", +! tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); + } + #endif +*************** +*** 646,786 **** + return 1; \ + } + +- +- /* adapted from eval.c */ +- +- #define listitem_alloc() (listitem_T *)alloc(sizeof(listitem_T)) +- +- static listitem_T * +- list_find (list_T *l, long n) +- { +- listitem_T *li; +- if (l == NULL || n < -l->lv_len || n >= l->lv_len) +- return NULL; +- if (n < 0) /* search backward? */ +- for (li = l->lv_last; n < -1; li = li->li_prev) +- n++; +- else /* search forward */ +- for (li = l->lv_first; n > 0; li = li->li_next) +- n--; +- return li; +- } +- +- static void +- list_remove (list_T *l, listitem_T *li) +- { +- listwatch_T *lw; +- --l->lv_len; +- /* fix watchers */ +- for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) +- if (lw->lw_item == li) +- lw->lw_item = li->li_next; +- /* fix list pointers */ +- if (li->li_next == NULL) /* last? */ +- l->lv_last = li->li_prev; +- else +- li->li_next->li_prev = li->li_prev; +- if (li->li_prev == NULL) /* first? */ +- l->lv_first = li->li_next; +- else +- li->li_prev->li_next = li->li_next; +- l->lv_idx_item = NULL; +- } +- +- static void +- list_append(list_T *l, listitem_T *item) +- { +- if (l->lv_last == NULL) /* empty list? */ +- l->lv_first = item; +- else +- l->lv_last->li_next = item; +- item->li_prev = l->lv_last; +- item->li_next = NULL; +- l->lv_last = item; +- ++l->lv_len; +- } +- +- static int +- list_insert_tv(list_T *l, typval_T *tv, listitem_T *item) +- { +- listitem_T *ni = listitem_alloc(); +- +- if (ni == NULL) +- return FAIL; +- copy_tv(tv, &ni->li_tv); +- if (item == NULL) +- list_append(l, ni); +- else +- { +- ni->li_prev = item->li_prev; +- ni->li_next = item; +- if (item->li_prev == NULL) +- { +- l->lv_first = ni; +- ++l->lv_idx; +- } +- else +- { +- item->li_prev->li_next = ni; +- l->lv_idx_item = NULL; +- } +- item->li_prev = ni; +- ++l->lv_len; +- } +- return OK; +- } +- +- /* set references */ +- +- static void set_ref_in_tv (typval_T *tv, int copyID); +- +- static void +- set_ref_in_dict(dict_T *d, int copyID) +- { +- hashtab_T *ht = &d->dv_hashtab; +- int n = ht->ht_used; +- hashitem_T *hi; +- for (hi = ht->ht_array; n > 0; ++hi) +- if (!HASHITEM_EMPTY(hi)) +- { +- dictitem_T *di = dict_lookup(hi); +- set_ref_in_tv(&di->di_tv, copyID); +- --n; +- } +- } +- +- static void +- set_ref_in_list(list_T *l, int copyID) +- { +- listitem_T *li; +- for (li = l->lv_first; li != NULL; li = li->li_next) +- set_ref_in_tv(&li->li_tv, copyID); +- } +- +- static void +- set_ref_in_tv(typval_T *tv, int copyID) +- { +- if (tv->v_type == VAR_LIST) +- { +- list_T *l = tv->vval.v_list; +- if (l != NULL && l->lv_copyID != copyID) +- { +- l->lv_copyID = copyID; +- set_ref_in_list(l, copyID); +- } +- } +- else if (tv->v_type == VAR_DICT) +- { +- dict_T *d = tv->vval.v_dict; +- if (d != NULL && d->dv_copyID != copyID) +- { +- d->dv_copyID = copyID; +- set_ref_in_dict(d, copyID); +- } +- } +- } +- +- + /* ======= List type ======= */ + + static luaV_List * +--- 646,651 ---- +*************** +*** 876,882 **** + if (li == NULL) return 0; + if (lua_isnil(L, 3)) /* remove? */ + { +! list_remove(l, li); + clear_tv(&li->li_tv); + vim_free(li); + } +--- 741,747 ---- + if (li == NULL) return 0; + if (lua_isnil(L, 3)) /* remove? */ + { +! list_remove(l, li, li); + clear_tv(&li->li_tv); + vim_free(li); + } +*************** +*** 904,911 **** + typval_T v; + lua_settop(L, 2); + luaV_totypval(L, 2, &v); +! copy_tv(&v, &li->li_tv); +! list_append(l, li); + } + lua_settop(L, 1); + return 1; +--- 769,775 ---- + typval_T v; + lua_settop(L, 2); + luaV_totypval(L, 2, &v); +! list_append_tv(l, &v); + } + lua_settop(L, 1); + return 1; +*************** +*** 1682,1688 **** + tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */ + } + lua_pop(L, 2); /* metatable and value */ +! set_ref_in_tv(&tv, copyID); + } + return 0; + } +--- 1546,1552 ---- + tv.vval.v_dict = (dict_T *) lua_touserdata(L, 4); /* key */ + } + lua_pop(L, 2); /* metatable and value */ +! set_ref_in_item(&tv, copyID); + } + return 0; + } +*** ../vim-7.3.568/src/if_py_both.h 2012-04-20 13:31:16.000000000 +0200 +--- src/if_py_both.h 2012-06-29 12:03:52.000000000 +0200 +*************** +*** 1,4 **** +! /* vi:set ts=8 sts=4 sw=4: + * + * VIM - Vi IMproved by Bram Moolenaar + * +--- 1,4 ---- +! /* vi:set ts=8 sts=4 sw=4 noet: + * + * VIM - Vi IMproved by Bram Moolenaar + * +*************** +*** 105,111 **** + return NULL; + Py_INCREF(list); + +! if (!PyList_Check(list)) { + PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings")); + Py_DECREF(list); + return NULL; +--- 105,112 ---- + return NULL; + Py_INCREF(list); + +! if (!PyList_Check(list)) +! { + PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings")); + Py_DECREF(list); + return NULL; +*************** +*** 119,125 **** + char *str = NULL; + PyInt len; + +! if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len)) { + PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings")); + Py_DECREF(list); + return NULL; +--- 120,127 ---- + char *str = NULL; + PyInt len; + +! if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len)) +! { + PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings")); + Py_DECREF(list); + return NULL; +*************** +*** 297,303 **** + { + PyObject *result; + PyObject *newObj; +! char ptrBuf[NUMBUFLEN]; + + /* Avoid infinite recursion */ + if (depth > 100) +--- 299,305 ---- + { + PyObject *result; + PyObject *newObj; +! char ptrBuf[sizeof(void *) * 2 + 3]; + + /* Avoid infinite recursion */ + if (depth > 100) +*************** +*** 312,320 **** + if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL) + || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL)) + { +! sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U, +! our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list +! : (long_u)our_tv->vval.v_dict); + result = PyDict_GetItemString(lookupDict, ptrBuf); + if (result != NULL) + { +--- 314,322 ---- + if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL) + || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL)) + { +! sprintf(ptrBuf, "%p", +! our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list +! : (void *)our_tv->vval.v_dict); + result = PyDict_GetItemString(lookupDict, ptrBuf); + if (result != NULL) + { +*************** +*** 374,509 **** + hashitem_T *hi; + dictitem_T *di; + +! PyDict_SetItemString(lookupDict, ptrBuf, result); + +! for (hi = ht->ht_array; todo > 0; ++hi) + { +! if (!HASHITEM_EMPTY(hi)) +! { +! --todo; +! +! di = dict_lookup(hi); +! newObj = VimToPython(&di->di_tv, depth + 1, lookupDict); +! PyDict_SetItemString(result, (char *)hi->hi_key, newObj); +! Py_DECREF(newObj); +! } + } + } + } +! else + { +! Py_INCREF(Py_None); +! result = Py_None; + } + +! return result; + } +- #endif + + static PyObject * +! VimEval(PyObject *self UNUSED, PyObject *args UNUSED) + { +! #ifdef FEAT_EVAL +! char *expr; +! typval_T *our_tv; +! PyObject *result; +! PyObject *lookup_dict; + +! if (!PyArg_ParseTuple(args, "s", &expr)) + return NULL; + +! Py_BEGIN_ALLOW_THREADS +! Python_Lock_Vim(); +! our_tv = eval_expr((char_u *)expr, NULL); +! +! Python_Release_Vim(); +! Py_END_ALLOW_THREADS +! +! if (our_tv == NULL) + { +! PyErr_SetVim(_("invalid expression")); + return NULL; + } + +- /* Convert the Vim type into a Python type. Create a dictionary that's +- * used to check for recursive loops. */ + lookup_dict = PyDict_New(); +! result = VimToPython(our_tv, 1, lookup_dict); + Py_DECREF(lookup_dict); + +! +! Py_BEGIN_ALLOW_THREADS +! Python_Lock_Vim(); +! free_tv(our_tv); +! Python_Release_Vim(); +! Py_END_ALLOW_THREADS +! +! return result; +! #else +! PyErr_SetVim(_("expressions disabled at compile time")); +! return NULL; +! #endif + } + +! /* +! * Vim module - Definitions +! */ +! +! static struct PyMethodDef VimMethods[] = { +! /* name, function, calling, documentation */ +! {"command", VimCommand, 1, "Execute a Vim ex-mode command" }, +! {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" }, +! { NULL, NULL, 0, NULL } + }; + + typedef struct + { + PyObject_HEAD +! buf_T *buf; +! } +! BufferObject; + +! #define INVALID_BUFFER_VALUE ((buf_T *)(-1)) +! +! /* +! * Buffer list object - Implementation +! */ + +! static PyInt +! BufListLength(PyObject *self UNUSED) + { +! buf_T *b = firstbuf; +! PyInt n = 0; + +! while (b) + { +! ++n; +! b = b->b_next; + } +! +! return n; + } + + static PyObject * +! BufListItem(PyObject *self UNUSED, PyInt n) + { +! buf_T *b; + +! for (b = firstbuf; b; b = b->b_next, --n) + { +! if (n == 0) +! return BufferNew(b); + } + +! PyErr_SetString(PyExc_IndexError, _("no such buffer")); +! return NULL; + } + +! typedef struct +! { +! PyObject_HEAD +! win_T *win; +! } WindowObject; + + #define INVALID_WINDOW_VALUE ((win_T *)(-1)) + +--- 376,1325 ---- + hashitem_T *hi; + dictitem_T *di; + +! PyDict_SetItemString(lookupDict, ptrBuf, result); +! +! for (hi = ht->ht_array; todo > 0; ++hi) +! { +! if (!HASHITEM_EMPTY(hi)) +! { +! --todo; +! +! di = dict_lookup(hi); +! newObj = VimToPython(&di->di_tv, depth + 1, lookupDict); +! PyDict_SetItemString(result, (char *)hi->hi_key, newObj); +! Py_DECREF(newObj); +! } +! } +! } +! } +! else +! { +! Py_INCREF(Py_None); +! result = Py_None; +! } +! +! return result; +! } +! #endif +! +! static PyObject * +! VimEval(PyObject *self UNUSED, PyObject *args UNUSED) +! { +! #ifdef FEAT_EVAL +! char *expr; +! typval_T *our_tv; +! PyObject *result; +! PyObject *lookup_dict; +! +! if (!PyArg_ParseTuple(args, "s", &expr)) +! return NULL; +! +! Py_BEGIN_ALLOW_THREADS +! Python_Lock_Vim(); +! our_tv = eval_expr((char_u *)expr, NULL); +! +! Python_Release_Vim(); +! Py_END_ALLOW_THREADS +! +! if (our_tv == NULL) +! { +! PyErr_SetVim(_("invalid expression")); +! return NULL; +! } +! +! /* Convert the Vim type into a Python type. Create a dictionary that's +! * used to check for recursive loops. */ +! lookup_dict = PyDict_New(); +! result = VimToPython(our_tv, 1, lookup_dict); +! Py_DECREF(lookup_dict); +! +! +! Py_BEGIN_ALLOW_THREADS +! Python_Lock_Vim(); +! free_tv(our_tv); +! Python_Release_Vim(); +! Py_END_ALLOW_THREADS +! +! return result; +! #else +! PyErr_SetVim(_("expressions disabled at compile time")); +! return NULL; +! #endif +! } +! +! static PyObject *ConvertToPyObject(typval_T *); +! +! static PyObject * +! VimEvalPy(PyObject *self UNUSED, PyObject *args UNUSED) +! { +! #ifdef FEAT_EVAL +! char *expr; +! typval_T *our_tv; +! PyObject *result; +! +! if (!PyArg_ParseTuple(args, "s", &expr)) +! return NULL; +! +! Py_BEGIN_ALLOW_THREADS +! Python_Lock_Vim(); +! our_tv = eval_expr((char_u *)expr, NULL); +! +! Python_Release_Vim(); +! Py_END_ALLOW_THREADS +! +! if (our_tv == NULL) +! { +! PyErr_SetVim(_("invalid expression")); +! return NULL; +! } +! +! result = ConvertToPyObject(our_tv); +! Py_BEGIN_ALLOW_THREADS +! Python_Lock_Vim(); +! free_tv(our_tv); +! Python_Release_Vim(); +! Py_END_ALLOW_THREADS +! +! return result; +! #else +! PyErr_SetVim(_("expressions disabled at compile time")); +! return NULL; +! #endif +! } +! +! static PyObject * +! VimStrwidth(PyObject *self UNUSED, PyObject *args) +! { +! char *expr; +! +! if (!PyArg_ParseTuple(args, "s", &expr)) +! return NULL; +! +! return PyLong_FromLong(mb_string2cells((char_u *)expr, STRLEN(expr))); +! } +! +! /* +! * Vim module - Definitions +! */ +! +! static struct PyMethodDef VimMethods[] = { +! /* name, function, calling, documentation */ +! {"command", VimCommand, 1, "Execute a Vim ex-mode command" }, +! {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" }, +! {"bindeval", VimEvalPy, 1, "Like eval(), but returns objects attached to vim ones"}, +! {"strwidth", VimStrwidth, 1, "Screen string width, counts as having width 1"}, +! { NULL, NULL, 0, NULL } +! }; +! +! typedef struct +! { +! PyObject_HEAD +! buf_T *buf; +! } BufferObject; +! +! #define INVALID_BUFFER_VALUE ((buf_T *)(-1)) +! +! /* +! * Buffer list object - Implementation +! */ +! +! static PyInt +! BufListLength(PyObject *self UNUSED) +! { +! buf_T *b = firstbuf; +! PyInt n = 0; +! +! while (b) +! { +! ++n; +! b = b->b_next; +! } +! +! return n; +! } +! +! static PyObject * +! BufListItem(PyObject *self UNUSED, PyInt n) +! { +! buf_T *b; +! +! for (b = firstbuf; b; b = b->b_next, --n) +! { +! if (n == 0) +! return BufferNew(b); +! } +! +! PyErr_SetString(PyExc_IndexError, _("no such buffer")); +! return NULL; +! } +! +! typedef struct +! { +! PyObject_HEAD +! win_T *win; +! } WindowObject; +! +! 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; +! PyObject *pll_obj; +! } pylinkedlist_T; +! +! static pylinkedlist_T *lastdict = NULL; +! static pylinkedlist_T *lastlist = NULL; +! +! static void +! pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last) +! { +! if (ref->pll_prev == NULL) +! { +! if (ref->pll_next == NULL) +! { +! *last = NULL; +! return; +! } +! } +! else +! ref->pll_prev->pll_next = ref->pll_next; +! +! if (ref->pll_next == NULL) +! *last = ref->pll_prev; +! else +! ref->pll_next->pll_prev = ref->pll_prev; +! } +! +! static void +! pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last) +! { +! if (*last == NULL) +! ref->pll_prev = NULL; +! else +! { +! (*last)->pll_next = ref; +! ref->pll_prev = *last; +! } +! ref->pll_next = NULL; +! ref->pll_obj = self; +! *last = ref; +! } +! +! static PyTypeObject DictionaryType; +! +! typedef struct +! { +! PyObject_HEAD +! dict_T *dict; +! pylinkedlist_T ref; +! } DictionaryObject; +! +! static PyObject * +! DictionaryNew(dict_T *dict) +! { +! DictionaryObject *self; +! +! self = PyObject_NEW(DictionaryObject, &DictionaryType); +! if (self == NULL) +! return NULL; +! self->dict = dict; +! ++dict->dv_refcount; +! +! pyll_add((PyObject *)(self), &self->ref, &lastdict); +! +! return (PyObject *)(self); +! } +! +! 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(-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); +! 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(-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 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 *val; +! DICTKEY_DECL +! +! DICTKEY_GET(NULL) +! +! val = dict_find(((DictionaryObject *) (self))->dict, key, -1); +! +! DICTKEY_UNREF +! +! return ConvertToPyObject(&val->di_tv); +! } +! +! static PyInt +! DictionaryAssItem(PyObject *self, PyObject *keyObject, PyObject *valObject) +! { +! char_u *key; +! typval_T tv; +! dict_T *d = ((DictionaryObject *)(self))->dict; +! dictitem_T *di; +! DICTKEY_DECL +! +! if (d->dv_lock) +! { +! PyErr_SetVim(_("dict is locked")); +! return -1; +! } +! +! DICTKEY_GET(-1) +! +! di = dict_find(d, key, -1); +! +! if (valObject == NULL) +! { +! if (di == NULL) +! { +! PyErr_SetString(PyExc_IndexError, _("no such key in dictionary")); +! return -1; +! } +! hashitem_T *hi = hash_find(&d->dv_hashtab, di->di_key); +! hash_remove(&d->dv_hashtab, hi); +! dictitem_free(di); +! return 0; +! } +! +! if (ConvertFromPyObject(valObject, &tv) == -1) +! { +! return -1; +! } +! +! if (di == NULL) +! { +! di = dictitem_alloc(key); +! if (di == NULL) +! { +! PyErr_NoMemory(); +! return -1; +! } +! di->di_tv.v_lock = 0; +! +! if (dict_add(d, di) == FAIL) +! { +! vim_free(di); +! PyErr_SetVim(_("failed to add key to dictionary")); +! return -1; +! } +! } +! else +! clear_tv(&di->di_tv); +! +! DICTKEY_UNREF +! +! copy_tv(&tv, &di->di_tv); +! return 0; +! } +! +! static PyObject * +! DictionaryListKeys(PyObject *self) +! { +! dict_T *dict = ((DictionaryObject *)(self))->dict; +! long_u todo = dict->dv_hashtab.ht_used; +! Py_ssize_t i = 0; +! PyObject *r; +! hashitem_T *hi; +! +! r = PyList_New(todo); +! for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi) +! { +! if (!HASHITEM_EMPTY(hi)) +! { +! PyList_SetItem(r, i, PyBytes_FromString((char *)(hi->hi_key))); +! --todo; +! ++i; +! } +! } +! return r; +! } +! +! static struct PyMethodDef DictionaryMethods[] = { +! {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""}, +! { NULL, NULL, 0, NULL } +! }; +! +! static PyTypeObject ListType; +! +! typedef struct +! { +! PyObject_HEAD +! list_T *list; +! pylinkedlist_T ref; +! } ListObject; +! +! static PyObject * +! ListNew(list_T *list) +! { +! ListObject *self; +! +! self = PyObject_NEW(ListObject, &ListType); +! if (self == NULL) +! return NULL; +! self->list = list; +! ++list->lv_refcount; +! +! pyll_add((PyObject *)(self), &self->ref, &lastlist); +! +! return (PyObject *)(self); +! } +! +! static int +! list_py_concat(list_T *l, PyObject *obj, PyObject *lookupDict) +! { +! Py_ssize_t i; +! Py_ssize_t lsize = PySequence_Size(obj); +! PyObject *litem; +! listitem_T *li; +! +! for(i=0; ili_tv.v_lock = 0; +! +! litem = PySequence_GetItem(obj, i); +! if (litem == NULL) +! return -1; +! if (_ConvertFromPyObject(litem, &li->li_tv, lookupDict) == -1) +! return -1; +! +! list_append(l, li); +! } +! 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) +! { +! return ((PyInt) (((ListObject *) (self))->list->lv_len)); +! } +! +! static PyObject * +! ListItem(PyObject *self, Py_ssize_t index) +! { +! listitem_T *li; +! +! if (index>=ListLength(self)) +! { +! PyErr_SetString(PyExc_IndexError, "list index out of range"); +! return NULL; +! } +! li = list_find(((ListObject *) (self))->list, (long) index); +! if (li == NULL) +! { +! PyErr_SetVim(_("internal error: failed to get vim list item")); +! return NULL; +! } +! return ConvertToPyObject(&li->li_tv); +! } +! +! #define PROC_RANGE \ +! if (last < 0) {\ +! if (last < -size) \ +! last = 0; \ +! else \ +! last += size; \ +! } \ +! if (first < 0) \ +! first = 0; \ +! if (first > size) \ +! first = size; \ +! if (last > size) \ +! last = size; +! +! static PyObject * +! ListSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last) +! { +! PyInt i; +! PyInt size = ListLength(self); +! PyInt n; +! PyObject *list; +! int reversed = 0; +! +! PROC_RANGE +! if (first >= last) +! first = last; +! +! n = last-first; +! list = PyList_New(n); +! if (list == NULL) +! return NULL; +! +! for (i = 0; i < n; ++i) +! { +! PyObject *item = ListItem(self, i); +! if (item == NULL) +! { +! Py_DECREF(list); +! return NULL; +! } +! +! if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item))) +! { +! Py_DECREF(item); +! Py_DECREF(list); +! return NULL; +! } +! } +! +! return list; +! } +! +! static int +! ListAssItem(PyObject *self, Py_ssize_t index, PyObject *obj) +! { +! typval_T tv; +! list_T *l = ((ListObject *) (self))->list; +! listitem_T *li; +! Py_ssize_t length = ListLength(self); +! +! if (l->lv_lock) +! { +! PyErr_SetVim(_("list is locked")); +! return -1; +! } +! if (index>length || (index==length && obj==NULL)) +! { +! PyErr_SetString(PyExc_IndexError, "list index out of range"); +! return -1; +! } +! +! if (obj == NULL) +! { +! li = list_find(l, (long) index); +! list_remove(l, li, li); +! clear_tv(&li->li_tv); +! vim_free(li); +! return 0; +! } +! +! if (ConvertFromPyObject(obj, &tv) == -1) +! return -1; +! +! if (index == length) +! { +! if (list_append_tv(l, &tv) == FAIL) +! { +! PyErr_SetVim(_("Failed to add item to list")); +! return -1; +! } +! } +! else +! { +! li = list_find(l, (long) index); +! clear_tv(&li->li_tv); +! copy_tv(&tv, &li->li_tv); +! } +! return 0; +! } +! +! static int +! ListAssSlice(PyObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj) +! { +! PyInt size = ListLength(self); +! Py_ssize_t i; +! Py_ssize_t lsize; +! PyObject *litem; +! listitem_T *li; +! listitem_T *next; +! typval_T v; +! list_T *l = ((ListObject *) (self))->list; +! +! if (l->lv_lock) +! { +! PyErr_SetVim(_("list is locked")); +! return -1; +! } +! +! PROC_RANGE + +! if (first == size) +! li = NULL; +! else +! { +! li = list_find(l, (long) first); +! if (li == NULL) +! { +! PyErr_SetVim(_("internal error: no vim list item")); +! return -1; +! } +! if (last > first) +! { +! i = last - first; +! while (i-- && li != NULL) + { +! next = li->li_next; +! listitem_remove(l, li); +! li = next; + } + } + } +! +! if (obj == NULL) +! return 0; +! +! if (!PyList_Check(obj)) + { +! PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice")); +! return -1; + } + +! lsize = PyList_Size(obj); +! +! for(i=0; ilist; +! PyObject *lookup_dict; + +! if (l->lv_lock) +! { +! PyErr_SetVim(_("list is locked")); + return NULL; ++ } + +! if (!PySequence_Check(obj)) + { +! PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists")); + return NULL; + } + + lookup_dict = PyDict_New(); +! if (list_py_concat(l, obj, lookup_dict) == -1) +! { +! Py_DECREF(lookup_dict); +! return NULL; +! } + Py_DECREF(lookup_dict); + +! Py_INCREF(self); +! return self; + } + +! static struct PyMethodDef ListMethods[] = { +! {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""}, +! { NULL, NULL, 0, NULL } + }; + + typedef struct + { + PyObject_HEAD +! char_u *name; +! } FunctionObject; + +! static PyTypeObject FunctionType; + +! static PyObject * +! FunctionNew(char_u *name) + { +! FunctionObject *self; + +! self = PyObject_NEW(FunctionObject, &FunctionType); +! if (self == NULL) +! return NULL; +! self->name = PyMem_New(char_u, STRLEN(name) + 1); +! if (self->name == NULL) + { +! PyErr_NoMemory(); +! return NULL; + } +! STRCPY(self->name, name); +! func_ref(name); +! return (PyObject *)(self); + } + + static PyObject * +! FunctionCall(PyObject *self, PyObject *argsObject, PyObject *kwargs) + { +! FunctionObject *this = (FunctionObject *)(self); +! char_u *name = this->name; +! typval_T args; +! typval_T selfdicttv; +! typval_T rettv; +! dict_T *selfdict = NULL; +! PyObject *selfdictObject; +! PyObject *result; +! int error; + +! if (ConvertFromPyObject(argsObject, &args) == -1) +! return NULL; +! +! if (kwargs != NULL) + { +! selfdictObject = PyDict_GetItemString(kwargs, "self"); +! if (selfdictObject != NULL) +! { +! if (!PyDict_Check(selfdictObject)) +! { +! PyErr_SetString(PyExc_TypeError, _("'self' argument must be a dictionary")); +! clear_tv(&args); +! return NULL; +! } +! if (ConvertFromPyObject(selfdictObject, &selfdicttv) == -1) +! return NULL; +! selfdict = selfdicttv.vval.v_dict; +! } + } + +! error = func_call(name, &args, selfdict, &rettv); +! if (error != OK) +! { +! result = NULL; +! PyErr_SetVim(_("failed to run function")); +! } +! else +! result = ConvertToPyObject(&rettv); +! +! /* FIXME Check what should really be cleared. */ +! clear_tv(&args); +! clear_tv(&rettv); +! /* +! * if (selfdict!=NULL) +! * clear_tv(selfdicttv); +! */ +! +! return result; + } + +! static struct PyMethodDef FunctionMethods[] = { +! {"__call__", (PyCFunction)FunctionCall, METH_VARARGS|METH_KEYWORDS, ""}, +! { NULL, NULL, 0, NULL } +! }; + + #define INVALID_WINDOW_VALUE ((win_T *)(-1)) + +*************** +*** 1567,1569 **** +--- 2383,2638 ---- + { NULL, NULL, 0, NULL } + }; + ++ static void ++ set_ref_in_py(const int copyID) ++ { ++ pylinkedlist_T *cur; ++ dict_T *dd; ++ list_T *ll; ++ ++ if (lastdict != NULL) ++ for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev) ++ { ++ dd = ((DictionaryObject *) (cur->pll_obj))->dict; ++ if (dd->dv_copyID != copyID) ++ { ++ dd->dv_copyID = copyID; ++ set_ref_in_ht(&dd->dv_hashtab, copyID); ++ } ++ } ++ ++ if (lastlist != NULL) ++ for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev) ++ { ++ ll = ((ListObject *) (cur->pll_obj))->list; ++ if (ll->lv_copyID != copyID) ++ { ++ ll->lv_copyID = copyID; ++ set_ref_in_list(ll, copyID); ++ } ++ } ++ } ++ ++ static int ++ set_string_copy(char_u *str, typval_T *tv) ++ { ++ tv->vval.v_string = vim_strsave(str); ++ if (tv->vval.v_string == NULL) ++ { ++ PyErr_NoMemory(); ++ return -1; ++ } ++ return 0; ++ } ++ ++ #ifdef FEAT_EVAL ++ typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *); ++ ++ static int ++ convert_dl(PyObject *obj, typval_T *tv, ++ pytotvfunc py_to_tv, PyObject *lookupDict) ++ { ++ PyObject *capsule; ++ char hexBuf[sizeof(void *) * 2 + 3]; ++ ++ sprintf(hexBuf, "%p", obj); ++ ++ capsule = PyDict_GetItemString(lookupDict, hexBuf); ++ if (capsule == NULL) ++ { ++ capsule = PyCapsule_New(tv, NULL, NULL); ++ PyDict_SetItemString(lookupDict, hexBuf, capsule); ++ Py_DECREF(capsule); ++ if (py_to_tv(obj, tv, lookupDict) == -1) ++ { ++ tv->v_type = VAR_UNKNOWN; ++ return -1; ++ } ++ /* As we are not using copy_tv which increments reference count we must ++ * do it ourself. */ ++ switch(tv->v_type) ++ { ++ case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break; ++ case VAR_LIST: ++tv->vval.v_list->lv_refcount; break; ++ } ++ } ++ else ++ { ++ typval_T *v = PyCapsule_GetPointer(capsule, NULL); ++ copy_tv(v, tv); ++ } ++ return 0; ++ } ++ ++ static int ++ ConvertFromPyObject(PyObject *obj, typval_T *tv) ++ { ++ PyObject *lookup_dict; ++ int r; ++ ++ lookup_dict = PyDict_New(); ++ r = _ConvertFromPyObject(obj, tv, lookup_dict); ++ Py_DECREF(lookup_dict); ++ return r; ++ } ++ ++ static int ++ _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookupDict) ++ { ++ if (obj->ob_type == &DictionaryType) ++ { ++ tv->v_type = VAR_DICT; ++ tv->vval.v_dict = (((DictionaryObject *)(obj))->dict); ++ ++tv->vval.v_dict->dv_refcount; ++ } ++ else if (obj->ob_type == &ListType) ++ { ++ tv->v_type = VAR_LIST; ++ tv->vval.v_list = (((ListObject *)(obj))->list); ++ ++tv->vval.v_list->lv_refcount; ++ } ++ else if (obj->ob_type == &FunctionType) ++ { ++ if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1) ++ return -1; ++ ++ tv->v_type = VAR_FUNC; ++ func_ref(tv->vval.v_string); ++ } ++ #if PY_MAJOR_VERSION >= 3 ++ else if (PyBytes_Check(obj)) ++ { ++ char_u *result = (char_u *) PyBytes_AsString(obj); ++ ++ if (result == NULL) ++ return -1; ++ ++ if (set_string_copy(result, tv) == -1) ++ return -1; ++ ++ tv->v_type = VAR_STRING; ++ } ++ else if (PyUnicode_Check(obj)) ++ { ++ PyObject *bytes; ++ char_u *result; ++ ++ bytes = PyString_AsBytes(obj); ++ if (bytes == NULL) ++ return -1; ++ ++ result = (char_u *) PyBytes_AsString(bytes); ++ if (result == NULL) ++ return -1; ++ ++ if (set_string_copy(result, tv) == -1) ++ { ++ Py_XDECREF(bytes); ++ return -1; ++ } ++ Py_XDECREF(bytes); ++ ++ tv->v_type = VAR_STRING; ++ } ++ #else ++ else if (PyUnicode_Check(obj)) ++ { ++ PyObject *bytes; ++ char_u *result; ++ ++ bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL); ++ if (bytes == NULL) ++ return -1; ++ ++ result=(char_u *) PyString_AsString(bytes); ++ if (result == NULL) ++ return -1; ++ ++ if (set_string_copy(result, tv) == -1) ++ { ++ Py_XDECREF(bytes); ++ return -1; ++ } ++ Py_XDECREF(bytes); ++ ++ tv->v_type = VAR_STRING; ++ } ++ else if (PyString_Check(obj)) ++ { ++ char_u *result = (char_u *) PyString_AsString(obj); ++ ++ if (result == NULL) ++ return -1; ++ ++ if (set_string_copy(result, tv) == -1) ++ return -1; ++ ++ tv->v_type = VAR_STRING; ++ } ++ else if (PyInt_Check(obj)) ++ { ++ tv->v_type = VAR_NUMBER; ++ tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj); ++ } ++ #endif ++ else if (PyLong_Check(obj)) ++ { ++ tv->v_type = VAR_NUMBER; ++ tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj); ++ } ++ else if (PyDict_Check(obj)) ++ return convert_dl(obj, tv, pydict_to_tv, lookupDict); ++ #ifdef FEAT_FLOAT ++ else if (PyFloat_Check(obj)) ++ { ++ tv->v_type = VAR_FLOAT; ++ tv->vval.v_float = (float_T) PyFloat_AsDouble(obj); ++ } ++ #endif ++ else if (PyIter_Check(obj)) ++ return convert_dl(obj, tv, pyiter_to_tv, lookupDict); ++ else if (PySequence_Check(obj)) ++ return convert_dl(obj, tv, pyseq_to_tv, lookupDict); ++ else if (PyMapping_Check(obj)) ++ return convert_dl(obj, tv, pymap_to_tv, lookupDict); ++ else ++ { ++ PyErr_SetString(PyExc_TypeError, _("unable to convert to vim structure")); ++ return -1; ++ } ++ return 0; ++ } ++ ++ static PyObject * ++ ConvertToPyObject(typval_T *tv) ++ { ++ if (tv == NULL) ++ { ++ PyErr_SetVim(_("NULL reference passed")); ++ return NULL; ++ } ++ switch (tv->v_type) ++ { ++ case VAR_STRING: ++ return PyBytes_FromString((char *) tv->vval.v_string); ++ case VAR_NUMBER: ++ return PyLong_FromLong((long) tv->vval.v_number); ++ #ifdef FEAT_FLOAT ++ case VAR_FLOAT: ++ return PyFloat_FromDouble((double) tv->vval.v_float); ++ #endif ++ case VAR_LIST: ++ return ListNew(tv->vval.v_list); ++ case VAR_DICT: ++ return DictionaryNew(tv->vval.v_dict); ++ case VAR_FUNC: ++ return FunctionNew(tv->vval.v_string); ++ case VAR_UNKNOWN: ++ Py_INCREF(Py_None); ++ return Py_None; ++ default: ++ PyErr_SetVim(_("internal error: invalid value type")); ++ return NULL; ++ } ++ } ++ #endif +*** ../vim-7.3.568/src/if_python.c 2011-08-28 16:00:14.000000000 +0200 +--- src/if_python.c 2012-06-29 12:47:48.000000000 +0200 +*************** +*** 1,4 **** +! /* vi:set ts=8 sts=4 sw=4: + * + * VIM - Vi IMproved by Bram Moolenaar + * +--- 1,4 ---- +! /* vi:set ts=8 sts=4 sw=4 noet: + * + * VIM - Vi IMproved by Bram Moolenaar + * +*************** +*** 56,61 **** +--- 56,63 ---- + + static void init_structs(void); + ++ #define PyBytes_FromString PyString_FromString ++ + /* No-op conversion functions, use with care! */ + #define PyString_AsBytes(obj) (obj) + #define PyString_FreeBytes(obj) +*************** +*** 122,132 **** +--- 124,136 ---- + /* This makes if_python.c compile without warnings against Python 2.5 + * on Win32 and Win64. */ + # undef PyRun_SimpleString ++ # undef PyRun_String + # undef PyArg_Parse + # undef PyArg_ParseTuple + # undef Py_BuildValue + # undef Py_InitModule4 + # undef Py_InitModule4_64 ++ # undef PyObject_CallMethod + + /* + * Wrapper defines +*************** +*** 134,139 **** +--- 138,144 ---- + # define PyArg_Parse dll_PyArg_Parse + # define PyArg_ParseTuple dll_PyArg_ParseTuple + # define PyMem_Free dll_PyMem_Free ++ # define PyMem_Malloc dll_PyMem_Malloc + # define PyDict_SetItemString dll_PyDict_SetItemString + # define PyErr_BadArgument dll_PyErr_BadArgument + # define PyErr_Clear dll_PyErr_Clear +*************** +*** 150,172 **** +--- 155,202 ---- + # endif + # define PyInt_AsLong dll_PyInt_AsLong + # define PyInt_FromLong dll_PyInt_FromLong ++ # define PyLong_AsLong dll_PyLong_AsLong ++ # define PyLong_FromLong dll_PyLong_FromLong + # define PyInt_Type (*dll_PyInt_Type) ++ # define PyLong_Type (*dll_PyLong_Type) + # define PyList_GetItem dll_PyList_GetItem + # define PyList_Append dll_PyList_Append + # define PyList_New dll_PyList_New + # define PyList_SetItem dll_PyList_SetItem + # define PyList_Size dll_PyList_Size + # define PyList_Type (*dll_PyList_Type) ++ # define PySequence_Check dll_PySequence_Check ++ # define PySequence_Size dll_PySequence_Size ++ # define PySequence_GetItem dll_PySequence_GetItem ++ # define PyTuple_Size dll_PyTuple_Size ++ # define PyTuple_GetItem dll_PyTuple_GetItem ++ # define PyTuple_Type (*dll_PyTuple_Type) + # define PyImport_ImportModule dll_PyImport_ImportModule + # define PyDict_New dll_PyDict_New + # define PyDict_GetItemString dll_PyDict_GetItemString ++ # define PyDict_Next dll_PyDict_Next ++ # ifdef PyMapping_Items ++ # define PY_NO_MAPPING_ITEMS ++ # else ++ # define PyMapping_Items dll_PyMapping_Items ++ # endif ++ # define PyObject_CallMethod dll_PyObject_CallMethod ++ # define PyMapping_Check dll_PyMapping_Check ++ # define PyIter_Next dll_PyIter_Next + # define PyModule_GetDict dll_PyModule_GetDict + # define PyRun_SimpleString dll_PyRun_SimpleString ++ # define PyRun_String dll_PyRun_String + # define PyString_AsString dll_PyString_AsString + # define PyString_FromString dll_PyString_FromString + # define PyString_FromStringAndSize dll_PyString_FromStringAndSize + # define PyString_Size dll_PyString_Size + # define PyString_Type (*dll_PyString_Type) ++ # define PyUnicode_Type (*dll_PyUnicode_Type) ++ # define PyUnicodeUCS4_AsEncodedString (*dll_PyUnicodeUCS4_AsEncodedString) ++ # define PyFloat_AsDouble dll_PyFloat_AsDouble ++ # define PyFloat_FromDouble dll_PyFloat_FromDouble ++ # define PyFloat_Type (*dll_PyFloat_Type) ++ # define PyImport_AddModule (*dll_PyImport_AddModule) + # define PySys_SetObject dll_PySys_SetObject + # define PySys_SetArgv dll_PySys_SetArgv + # define PyType_Type (*dll_PyType_Type) +*************** +*** 179,186 **** +--- 209,218 ---- + # define Py_Finalize dll_Py_Finalize + # define Py_IsInitialized dll_Py_IsInitialized + # define _PyObject_New dll__PyObject_New ++ # define _PyObject_NextNotImplemented (*dll__PyObject_NextNotImplemented) + # define _Py_NoneStruct (*dll__Py_NoneStruct) + # define PyObject_Init dll__PyObject_Init ++ # define PyObject_GetIter dll_PyObject_GetIter + # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000 + # define PyType_IsSubtype dll_PyType_IsSubtype + # endif +*************** +*** 188,193 **** +--- 220,227 ---- + # define PyObject_Malloc dll_PyObject_Malloc + # define PyObject_Free dll_PyObject_Free + # endif ++ # define PyCapsule_New dll_PyCapsule_New ++ # define PyCapsule_GetPointer dll_PyCapsule_GetPointer + + /* + * Pointers for dynamic link +*************** +*** 195,200 **** +--- 229,235 ---- + static int(*dll_PyArg_Parse)(PyObject *, char *, ...); + static int(*dll_PyArg_ParseTuple)(PyObject *, char *, ...); + static int(*dll_PyMem_Free)(void *); ++ static void* (*dll_PyMem_Malloc)(size_t); + static int(*dll_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item); + static int(*dll_PyErr_BadArgument)(void); + static void(*dll_PyErr_Clear)(void); +*************** +*** 208,233 **** + # ifdef PY_CAN_RECURSE + static PyGILState_STATE (*dll_PyGILState_Ensure)(void); + static void (*dll_PyGILState_Release)(PyGILState_STATE); +! #endif + static long(*dll_PyInt_AsLong)(PyObject *); + static PyObject*(*dll_PyInt_FromLong)(long); + static PyTypeObject* dll_PyInt_Type; + static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt); + static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *); + static PyObject*(*dll_PyList_New)(PyInt size); + static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *); + static PyInt(*dll_PyList_Size)(PyObject *); + static PyTypeObject* dll_PyList_Type; + static PyObject*(*dll_PyImport_ImportModule)(const char *); + static PyObject*(*dll_PyDict_New)(void); + static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *); + static PyObject*(*dll_PyModule_GetDict)(PyObject *); + static int(*dll_PyRun_SimpleString)(char *); + static char*(*dll_PyString_AsString)(PyObject *); + static PyObject*(*dll_PyString_FromString)(const char *); + static PyObject*(*dll_PyString_FromStringAndSize)(const char *, PyInt); + static PyInt(*dll_PyString_Size)(PyObject *); + static PyTypeObject* dll_PyString_Type; + static int(*dll_PySys_SetObject)(char *, PyObject *); + static int(*dll_PySys_SetArgv)(int, char **); + static PyTypeObject* dll_PyType_Type; +--- 243,290 ---- + # ifdef PY_CAN_RECURSE + static PyGILState_STATE (*dll_PyGILState_Ensure)(void); + static void (*dll_PyGILState_Release)(PyGILState_STATE); +! # endif + static long(*dll_PyInt_AsLong)(PyObject *); + static PyObject*(*dll_PyInt_FromLong)(long); ++ static long(*dll_PyLong_AsLong)(PyObject *); ++ static PyObject*(*dll_PyLong_FromLong)(long); + static PyTypeObject* dll_PyInt_Type; ++ static PyTypeObject* dll_PyLong_Type; + static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt); + static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *); + static PyObject*(*dll_PyList_New)(PyInt size); + static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *); + static PyInt(*dll_PyList_Size)(PyObject *); + static PyTypeObject* dll_PyList_Type; ++ static int (*dll_PySequence_Check)(PyObject *); ++ static PyInt(*dll_PySequence_Size)(PyObject *); ++ static PyObject*(*dll_PySequence_GetItem)(PyObject *, PyInt); ++ static PyInt(*dll_PyTuple_Size)(PyObject *); ++ static PyObject*(*dll_PyTuple_GetItem)(PyObject *, PyInt); ++ static PyTypeObject* dll_PyTuple_Type; + static PyObject*(*dll_PyImport_ImportModule)(const char *); + static PyObject*(*dll_PyDict_New)(void); + static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *); ++ static int (*dll_PyDict_Next)(PyObject *, Py_ssize_t *, PyObject **, PyObject **); ++ # ifndef PY_NO_MAPPING_ITEMS ++ static PyObject* (*dll_PyMapping_Items)(PyObject *); ++ # endif ++ static PyObject* (*dll_PyObject_CallMethod)(PyObject *, char *, PyObject *); ++ static int (*dll_PyMapping_Check)(PyObject *); ++ static PyObject* (*dll_PyIter_Next)(PyObject *); + static PyObject*(*dll_PyModule_GetDict)(PyObject *); + static int(*dll_PyRun_SimpleString)(char *); ++ static PyObject *(*dll_PyRun_String)(char *, int, PyObject *, PyObject *); + static char*(*dll_PyString_AsString)(PyObject *); + static PyObject*(*dll_PyString_FromString)(const char *); + static PyObject*(*dll_PyString_FromStringAndSize)(const char *, PyInt); + static PyInt(*dll_PyString_Size)(PyObject *); + static PyTypeObject* dll_PyString_Type; ++ static PyTypeObject* dll_PyUnicode_Type; ++ static PyObject *(*PyUnicodeUCS4_AsEncodedString)(PyObject *, char *, char *); ++ static double(*dll_PyFloat_AsDouble)(PyObject *); ++ static PyObject*(*dll_PyFloat_FromDouble)(double); ++ static PyTypeObject* dll_PyFloat_Type; + static int(*dll_PySys_SetObject)(char *, PyObject *); + static int(*dll_PySys_SetArgv)(int, char **); + static PyTypeObject* dll_PyType_Type; +*************** +*** 235,246 **** +--- 292,306 ---- + static PyObject*(*dll_Py_BuildValue)(char *, ...); + static PyObject*(*dll_Py_FindMethod)(struct PyMethodDef[], PyObject *, char *); + static PyObject*(*dll_Py_InitModule4)(char *, struct PyMethodDef *, char *, PyObject *, int); ++ static PyObject*(*dll_PyImport_AddModule)(char *); + static void(*dll_Py_SetPythonHome)(char *home); + static void(*dll_Py_Initialize)(void); + static void(*dll_Py_Finalize)(void); + static int(*dll_Py_IsInitialized)(void); + static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *); + static PyObject*(*dll__PyObject_Init)(PyObject *, PyTypeObject *); ++ static PyObject* (*dll_PyObject_GetIter)(PyObject *); ++ static iternextfunc dll__PyObject_NextNotImplemented; + static PyObject* dll__Py_NoneStruct; + # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000 + static int (*dll_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *); +*************** +*** 249,254 **** +--- 309,316 ---- + static void* (*dll_PyObject_Malloc)(size_t); + static void (*dll_PyObject_Free)(void*); + # endif ++ static PyObject* (*dll_PyCapsule_New)(void *, char *, PyCapsule_Destructor); ++ static void* (*dll_PyCapsule_GetPointer)(PyObject *, char *); + + static HINSTANCE hinstPython = 0; /* Instance of python.dll */ + +*************** +*** 278,283 **** +--- 340,346 ---- + {"PyArg_Parse", (PYTHON_PROC*)&dll_PyArg_Parse}, + {"PyArg_ParseTuple", (PYTHON_PROC*)&dll_PyArg_ParseTuple}, + {"PyMem_Free", (PYTHON_PROC*)&dll_PyMem_Free}, ++ {"PyMem_Malloc", (PYTHON_PROC*)&dll_PyMem_Malloc}, + {"PyDict_SetItemString", (PYTHON_PROC*)&dll_PyDict_SetItemString}, + {"PyErr_BadArgument", (PYTHON_PROC*)&dll_PyErr_BadArgument}, + {"PyErr_Clear", (PYTHON_PROC*)&dll_PyErr_Clear}, +*************** +*** 294,316 **** +--- 357,402 ---- + # endif + {"PyInt_AsLong", (PYTHON_PROC*)&dll_PyInt_AsLong}, + {"PyInt_FromLong", (PYTHON_PROC*)&dll_PyInt_FromLong}, ++ {"PyLong_AsLong", (PYTHON_PROC*)&dll_PyLong_AsLong}, ++ {"PyLong_FromLong", (PYTHON_PROC*)&dll_PyLong_FromLong}, + {"PyInt_Type", (PYTHON_PROC*)&dll_PyInt_Type}, ++ {"PyLong_Type", (PYTHON_PROC*)&dll_PyLong_Type}, + {"PyList_GetItem", (PYTHON_PROC*)&dll_PyList_GetItem}, + {"PyList_Append", (PYTHON_PROC*)&dll_PyList_Append}, + {"PyList_New", (PYTHON_PROC*)&dll_PyList_New}, + {"PyList_SetItem", (PYTHON_PROC*)&dll_PyList_SetItem}, + {"PyList_Size", (PYTHON_PROC*)&dll_PyList_Size}, + {"PyList_Type", (PYTHON_PROC*)&dll_PyList_Type}, ++ {"PySequence_GetItem", (PYTHON_PROC*)&dll_PySequence_GetItem}, ++ {"PySequence_Size", (PYTHON_PROC*)&dll_PySequence_Size}, ++ {"PySequence_Check", (PYTHON_PROC*)&dll_PySequence_Check}, ++ {"PyTuple_GetItem", (PYTHON_PROC*)&dll_PyTuple_GetItem}, ++ {"PyTuple_Size", (PYTHON_PROC*)&dll_PyTuple_Size}, ++ {"PyTuple_Type", (PYTHON_PROC*)&dll_PyTuple_Type}, + {"PyImport_ImportModule", (PYTHON_PROC*)&dll_PyImport_ImportModule}, + {"PyDict_GetItemString", (PYTHON_PROC*)&dll_PyDict_GetItemString}, ++ {"PyDict_Next", (PYTHON_PROC*)&dll_PyDict_Next}, + {"PyDict_New", (PYTHON_PROC*)&dll_PyDict_New}, ++ # ifndef PY_NO_MAPPING_ITEMS ++ {"PyMapping_Items", (PYTHON_PROC*)&dll_PyMapping_Items}, ++ # endif ++ {"PyObject_CallMethod", (PYTHON_PROC*)&dll_PyObject_CallMethod}, ++ {"PyMapping_Check", (PYTHON_PROC*)&dll_PyMapping_Check}, ++ {"PyIter_Next", (PYTHON_PROC*)&dll_PyIter_Next}, + {"PyModule_GetDict", (PYTHON_PROC*)&dll_PyModule_GetDict}, + {"PyRun_SimpleString", (PYTHON_PROC*)&dll_PyRun_SimpleString}, ++ {"PyRun_String", (PYTHON_PROC*)&dll_PyRun_String}, + {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString}, + {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString}, + {"PyString_FromStringAndSize", (PYTHON_PROC*)&dll_PyString_FromStringAndSize}, + {"PyString_Size", (PYTHON_PROC*)&dll_PyString_Size}, + {"PyString_Type", (PYTHON_PROC*)&dll_PyString_Type}, ++ {"PyUnicode_Type", (PYTHON_PROC*)&dll_PyUnicode_Type}, ++ {"PyUnicodeUCS4_AsEncodedString", (PYTHON_PROC*)&dll_PyUnicodeUCS4_AsEncodedString}, ++ {"PyFloat_Type", (PYTHON_PROC*)&dll_PyFloat_Type}, ++ {"PyFloat_AsDouble", (PYTHON_PROC*)&dll_PyFloat_AsDouble}, ++ {"PyFloat_FromDouble", (PYTHON_PROC*)&dll_PyFloat_FromDouble}, ++ {"PyImport_AddModule", (PYTHON_PROC*)&dll_PyImport_AddModule}, + {"PySys_SetObject", (PYTHON_PROC*)&dll_PySys_SetObject}, + {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv}, + {"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type}, +*************** +*** 328,333 **** +--- 414,421 ---- + {"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized}, + {"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New}, + {"PyObject_Init", (PYTHON_PROC*)&dll__PyObject_Init}, ++ {"PyObject_GetIter", (PYTHON_PROC*)&dll_PyObject_GetIter}, ++ {"_PyObject_NextNotImplemented", (PYTHON_PROC*)&dll__PyObject_NextNotImplemented}, + {"_Py_NoneStruct", (PYTHON_PROC*)&dll__Py_NoneStruct}, + # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000 + {"PyType_IsSubtype", (PYTHON_PROC*)&dll_PyType_IsSubtype}, +*************** +*** 336,341 **** +--- 424,431 ---- + {"PyObject_Malloc", (PYTHON_PROC*)&dll_PyObject_Malloc}, + {"PyObject_Free", (PYTHON_PROC*)&dll_PyObject_Free}, + # endif ++ {"PyCapsule_New", (PYTHON_PROC*)&dll_PyCapsule_New}, ++ {"PyCapsule_GetPointer", (PYTHON_PROC*)&dll_PyCapsule_GetPointer}, + {"", NULL}, + }; + +*************** +*** 434,443 **** +--- 524,548 ---- + + static PyObject *BufferNew (buf_T *); + static PyObject *WindowNew(win_T *); ++ static PyObject *DictionaryNew(dict_T *); + static PyObject *LineToString(const char *); + + static PyTypeObject RangeType; + ++ static int initialised = 0; ++ #define PYINITIALISED initialised ++ ++ /* Add conversion from PyInt? */ ++ #define DICTKEY_GET(err) \ ++ if (!PyString_Check(keyObject)) \ ++ { \ ++ PyErr_SetString(PyExc_TypeError, _("only string keys are allowed")); \ ++ return err; \ ++ } \ ++ key = (char_u *) PyString_AsString(keyObject); ++ #define DICTKEY_UNREF ++ #define DICTKEY_DECL ++ + /* + * Include the code shared with if_python3.c + */ +*************** +*** 451,456 **** +--- 556,563 ---- + static PyInt RangeStart; + static PyInt RangeEnd; + ++ static PyObject *globals; ++ + static void PythonIO_Flush(void); + static int PythonIO_Init(void); + static int PythonMod_Init(void); +*************** +*** 466,473 **** + * 1. Python interpreter main program. + */ + +- static int initialised = 0; +- + #if PYTHON_API_VERSION < 1007 /* Python 1.4 */ + typedef PyObject PyThreadState; + #endif +--- 573,578 ---- +*************** +*** 581,586 **** +--- 686,693 ---- + if (PythonMod_Init()) + goto fail; + ++ globals = PyModule_GetDict(PyImport_AddModule("__main__")); ++ + /* Remove the element from sys.path that was added because of our + * argv[0] value in PythonMod_Init(). Previously we used an empty + * string, but dependinding on the OS we then get an empty entry or +*************** +*** 609,615 **** + * External interface + */ + static void +! DoPythonCommand(exarg_T *eap, const char *cmd) + { + #ifndef PY_CAN_RECURSE + static int recursive = 0; +--- 716,722 ---- + * External interface + */ + static void +! DoPythonCommand(exarg_T *eap, const char *cmd, typval_T *rettv) + { + #ifndef PY_CAN_RECURSE + static int recursive = 0; +*************** +*** 639,646 **** + if (Python_Init()) + goto theend; + +! RangeStart = eap->line1; +! RangeEnd = eap->line2; + Python_Release_Vim(); /* leave vim */ + + #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) +--- 746,761 ---- + if (Python_Init()) + goto theend; + +! if (rettv == NULL) +! { +! RangeStart = eap->line1; +! RangeEnd = eap->line2; +! } +! else +! { +! RangeStart = (PyInt) curwin->w_cursor.lnum; +! RangeEnd = RangeStart; +! } + Python_Release_Vim(); /* leave vim */ + + #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) +*************** +*** 658,664 **** + + Python_RestoreThread(); /* enter python */ + +! PyRun_SimpleString((char *)(cmd)); + + Python_SaveThread(); /* leave python */ + +--- 773,795 ---- + + Python_RestoreThread(); /* enter python */ + +! if (rettv == NULL) +! PyRun_SimpleString((char *)(cmd)); +! else +! { +! PyObject *r; +! +! r = PyRun_String((char *)(cmd), Py_eval_input, globals, globals); +! if (r == NULL) +! EMSG(_("E858: Eval did not return a valid python object")); +! else +! { +! if (ConvertFromPyObject(r, rettv) == -1) +! EMSG(_("E859: Failed to convert returned python object to vim value")); +! Py_DECREF(r); +! } +! PyErr_Clear(); +! } + + Python_SaveThread(); /* leave python */ + +*************** +*** 680,686 **** + #ifndef PY_CAN_RECURSE + --recursive; + #endif +! return; /* keeps lint happy */ + } + + /* +--- 811,817 ---- + #ifndef PY_CAN_RECURSE + --recursive; + #endif +! return; + } + + /* +*************** +*** 695,703 **** + if (!eap->skip) + { + if (script == NULL) +! DoPythonCommand(eap, (char *)eap->arg); + else +! DoPythonCommand(eap, (char *)script); + } + vim_free(script); + } +--- 826,834 ---- + if (!eap->skip) + { + if (script == NULL) +! DoPythonCommand(eap, (char *)eap->arg, NULL); + else +! DoPythonCommand(eap, (char *)script, NULL); + } + vim_free(script); + } +*************** +*** 743,749 **** + *p++ = '\0'; + + /* Execute the file */ +! DoPythonCommand(eap, buffer); + } + + /****************************************************** +--- 874,880 ---- + *p++ = '\0'; + + /* Execute the file */ +! DoPythonCommand(eap, buffer, NULL); + } + + /****************************************************** +*************** +*** 765,778 **** + static int + OutputSetattr(PyObject *self, char *name, PyObject *val) + { +! if (val == NULL) { + PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes")); + return -1; + } + + if (strcmp(name, "softspace") == 0) + { +! if (!PyInt_Check(val)) { + PyErr_SetString(PyExc_TypeError, _("softspace must be an integer")); + return -1; + } +--- 896,911 ---- + static int + OutputSetattr(PyObject *self, char *name, PyObject *val) + { +! if (val == NULL) +! { + PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes")); + return -1; + } + + if (strcmp(name, "softspace") == 0) + { +! if (!PyInt_Check(val)) +! { + PyErr_SetString(PyExc_TypeError, _("softspace must be an integer")); + return -1; + } +*************** +*** 800,805 **** +--- 933,941 ---- + * 3. Implementation of the Vim module for Python + */ + ++ static PyObject *ConvertToPyObject(typval_T *); ++ static int ConvertFromPyObject(PyObject *, typval_T *); ++ + /* Window type - Implementation functions + * -------------------------------------- + */ +*************** +*** 1441,1446 **** +--- 1577,1748 ---- + return result; + } + ++ static void DictionaryDestructor(PyObject *); ++ static PyObject *DictionaryGetattr(PyObject *, char*); ++ ++ static PyMappingMethods DictionaryAsMapping = { ++ (PyInquiry) DictionaryLength, ++ (binaryfunc) DictionaryItem, ++ (objobjargproc) DictionaryAssItem, ++ }; ++ ++ static PyTypeObject DictionaryType = { ++ PyObject_HEAD_INIT(0) ++ 0, ++ "vimdictionary", ++ sizeof(DictionaryObject), ++ 0, ++ ++ (destructor) DictionaryDestructor, ++ (printfunc) 0, ++ (getattrfunc) DictionaryGetattr, ++ (setattrfunc) 0, ++ (cmpfunc) 0, ++ (reprfunc) 0, ++ ++ 0, /* as number */ ++ 0, /* as sequence */ ++ &DictionaryAsMapping, /* as mapping */ ++ ++ (hashfunc) 0, ++ (ternaryfunc) 0, ++ (reprfunc) 0, ++ }; ++ ++ static void ++ DictionaryDestructor(PyObject *self) ++ { ++ DictionaryObject *this = ((DictionaryObject *) (self)); ++ ++ pyll_remove(&this->ref, &lastdict); ++ dict_unref(this->dict); ++ ++ Py_DECREF(self); ++ } ++ ++ static PyObject * ++ DictionaryGetattr(PyObject *self, char *name) ++ { ++ return Py_FindMethod(DictionaryMethods, self, name); ++ } ++ ++ static void ListDestructor(PyObject *); ++ static PyObject *ListGetattr(PyObject *, char *); ++ ++ static PySequenceMethods ListAsSeq = { ++ (PyInquiry) ListLength, ++ (binaryfunc) 0, ++ (PyIntArgFunc) 0, ++ (PyIntArgFunc) ListItem, ++ (PyIntIntArgFunc) ListSlice, ++ (PyIntObjArgProc) ListAssItem, ++ (PyIntIntObjArgProc) ListAssSlice, ++ (objobjproc) 0, ++ #if PY_MAJOR_VERSION >= 2 ++ (binaryfunc) ListConcatInPlace, ++ 0, ++ #endif ++ }; ++ ++ static PyTypeObject ListType = { ++ PyObject_HEAD_INIT(0) ++ 0, ++ "vimlist", ++ sizeof(ListObject), ++ 0, ++ ++ (destructor) ListDestructor, ++ (printfunc) 0, ++ (getattrfunc) ListGetattr, ++ (setattrfunc) 0, ++ (cmpfunc) 0, ++ (reprfunc) 0, ++ ++ 0, /* as number */ ++ &ListAsSeq, /* as sequence */ ++ 0, /* as mapping */ ++ ++ (hashfunc) 0, ++ (ternaryfunc) 0, ++ (reprfunc) 0, ++ }; ++ ++ static void ++ ListDestructor(PyObject *self) ++ { ++ ListObject *this = ((ListObject *) (self)); ++ ++ pyll_remove(&this->ref, &lastlist); ++ list_unref(this->list); ++ ++ Py_DECREF(self); ++ } ++ ++ static PyObject * ++ ListGetattr(PyObject *self, char *name) ++ { ++ return Py_FindMethod(ListMethods, self, name); ++ } ++ ++ static void FunctionDestructor(PyObject *); ++ static PyObject *FunctionGetattr(PyObject *, char *); ++ ++ static PyTypeObject FunctionType = { ++ PyObject_HEAD_INIT(0) ++ 0, ++ "vimfunction", ++ sizeof(FunctionObject), ++ 0, ++ ++ (destructor) FunctionDestructor, ++ (printfunc) 0, ++ (getattrfunc) FunctionGetattr, ++ (setattrfunc) 0, ++ (cmpfunc) 0, ++ (reprfunc) 0, ++ ++ 0, /* as number */ ++ 0, /* as sequence */ ++ 0, /* as mapping */ ++ ++ (hashfunc) 0, ++ (ternaryfunc) FunctionCall, ++ (reprfunc) 0, ++ }; ++ ++ static void ++ FunctionDestructor(PyObject *self) ++ { ++ FunctionObject *this = (FunctionObject *) (self); ++ ++ func_unref(this->name); ++ PyMem_Del(this->name); ++ ++ Py_DECREF(self); ++ } ++ ++ static PyObject * ++ FunctionGetattr(PyObject *self, char *name) ++ { ++ FunctionObject *this = (FunctionObject *)(self); ++ ++ if (strcmp(name, "name") == 0) ++ return PyString_FromString((char *)(this->name)); ++ else ++ return Py_FindMethod(FunctionMethods, self, name); ++ } ++ ++ void ++ do_pyeval (char_u *str, typval_T *rettv) ++ { ++ DoPythonCommand(NULL, (char *) str, rettv); ++ switch(rettv->v_type) ++ { ++ case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break; ++ case VAR_LIST: ++rettv->vval.v_list->lv_refcount; break; ++ case VAR_FUNC: func_ref(rettv->vval.v_string); break; ++ } ++ } + + /* Don't generate a prototype for the next function, it generates an error on + * newer Python versions. */ +*************** +*** 1453,1458 **** +--- 1755,1766 ---- + } + #endif /* Python 1.4 */ + ++ void ++ set_ref_in_python (int copyID) ++ { ++ set_ref_in_py(copyID); ++ } ++ + static void + init_structs(void) + { +*** ../vim-7.3.568/src/if_python3.c 2012-02-04 20:17:21.000000000 +0100 +--- src/if_python3.c 2012-06-29 11:54:10.000000000 +0200 +*************** +*** 77,83 **** + + #define PyInt Py_ssize_t + #define PyString_Check(obj) PyUnicode_Check(obj) +! #define PyString_AsBytes(obj) PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, CODEC_ERROR_HANDLER); + #define PyString_FreeBytes(obj) Py_XDECREF(bytes) + #define PyString_AsString(obj) PyBytes_AsString(obj) + #define PyString_Size(obj) PyBytes_GET_SIZE(bytes) +--- 77,83 ---- + + #define PyInt Py_ssize_t + #define PyString_Check(obj) PyUnicode_Check(obj) +! #define PyString_AsBytes(obj) PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, CODEC_ERROR_HANDLER) + #define PyString_FreeBytes(obj) Py_XDECREF(bytes) + #define PyString_AsString(obj) PyBytes_AsString(obj) + #define PyString_Size(obj) PyBytes_GET_SIZE(bytes) +*************** +*** 109,114 **** +--- 109,115 ---- + # undef PyArg_ParseTuple + # define PyArg_ParseTuple py3_PyArg_ParseTuple + # define PyMem_Free py3_PyMem_Free ++ # define PyMem_Malloc py3_PyMem_Malloc + # define PyDict_SetItemString py3_PyDict_SetItemString + # define PyErr_BadArgument py3_PyErr_BadArgument + # define PyErr_Clear py3_PyErr_Clear +*************** +*** 128,141 **** +--- 129,155 ---- + # define PyList_New py3_PyList_New + # define PyList_SetItem py3_PyList_SetItem + # define PyList_Size py3_PyList_Size ++ # define PySequence_Check py3_PySequence_Check ++ # define PySequence_Size py3_PySequence_Size ++ # define PySequence_GetItem py3_PySequence_GetItem ++ # define PyTuple_Size py3_PyTuple_Size ++ # define PyTuple_GetItem py3_PyTuple_GetItem + # define PySlice_GetIndicesEx py3_PySlice_GetIndicesEx + # define PyImport_ImportModule py3_PyImport_ImportModule ++ # define PyImport_AddModule py3_PyImport_AddModule + # define PyObject_Init py3__PyObject_Init + # define PyDict_New py3_PyDict_New + # define PyDict_GetItemString py3_PyDict_GetItemString ++ # define PyDict_Next py3_PyDict_Next ++ # define PyMapping_Check py3_PyMapping_Check ++ # define PyMapping_Items py3_PyMapping_Items ++ # define PyIter_Next py3_PyIter_Next ++ # define PyObject_GetIter py3_PyObject_GetIter + # define PyModule_GetDict py3_PyModule_GetDict + #undef PyRun_SimpleString + # define PyRun_SimpleString py3_PyRun_SimpleString ++ #undef PyRun_String ++ # define PyRun_String py3_PyRun_String + # define PySys_SetObject py3_PySys_SetObject + # define PySys_SetArgv py3_PySys_SetArgv + # define PyType_Type (*py3_PyType_Type) +*************** +*** 147,152 **** +--- 161,167 ---- + # define Py_Finalize py3_Py_Finalize + # define Py_IsInitialized py3_Py_IsInitialized + # define _Py_NoneStruct (*py3__Py_NoneStruct) ++ # define _PyObject_NextNotImplemented (*py3__PyObject_NextNotImplemented) + # define PyModule_AddObject py3_PyModule_AddObject + # define PyImport_AppendInittab py3_PyImport_AppendInittab + # define _PyUnicode_AsString py3__PyUnicode_AsString +*************** +*** 154,161 **** +--- 169,181 ---- + # define PyUnicode_AsEncodedString py3_PyUnicode_AsEncodedString + # undef PyBytes_AsString + # define PyBytes_AsString py3_PyBytes_AsString ++ # undef PyBytes_FromString ++ # define PyBytes_FromString py3_PyBytes_FromString ++ # define PyFloat_FromDouble py3_PyFloat_FromDouble ++ # define PyFloat_AsDouble py3_PyFloat_AsDouble + # define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr + # define PySlice_Type (*py3_PySlice_Type) ++ # define PyFloat_Type (*py3_PyFloat_Type) + # define PyErr_NewException py3_PyErr_NewException + # ifdef Py_DEBUG + # define _Py_NegativeRefcount py3__Py_NegativeRefcount +*************** +*** 174,179 **** +--- 194,202 ---- + # define PyUnicode_FromString py3_PyUnicode_FromString + # undef PyUnicode_Decode + # define PyUnicode_Decode py3_PyUnicode_Decode ++ # define PyType_IsSubtype py3_PyType_IsSubtype ++ # define PyCapsule_New py3_PyCapsule_New ++ # define PyCapsule_GetPointer py3_PyCapsule_GetPointer + + # ifdef Py_DEBUG + # undef PyObject_NEW +*************** +*** 194,215 **** +--- 217,250 ---- + static int (*py3_PySys_SetObject)(char *, PyObject *); + static PyObject* (*py3_PyList_Append)(PyObject *, PyObject *); + static Py_ssize_t (*py3_PyList_Size)(PyObject *); ++ static int (*py3_PySequence_Check)(PyObject *); ++ static Py_ssize_t (*py3_PySequence_Size)(PyObject *); ++ static PyObject* (*py3_PySequence_GetItem)(PyObject *, Py_ssize_t); ++ static Py_ssize_t (*py3_PyTuple_Size)(PyObject *); ++ static PyObject* (*py3_PyTuple_GetItem)(PyObject *, Py_ssize_t); ++ static int (*py3_PyMapping_Check)(PyObject *); ++ static PyObject* (*py3_PyMapping_Items)(PyObject *); + static int (*py3_PySlice_GetIndicesEx)(PyObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength); + static PyObject* (*py3_PyErr_NoMemory)(void); + static void (*py3_Py_Finalize)(void); + static void (*py3_PyErr_SetString)(PyObject *, const char *); + static int (*py3_PyRun_SimpleString)(char *); ++ static PyObject* (*py3_PyRun_String)(char *, int, PyObject *, PyObject *); + static PyObject* (*py3_PyList_GetItem)(PyObject *, Py_ssize_t); + static PyObject* (*py3_PyImport_ImportModule)(const char *); ++ static PyObject* (*py3_PyImport_AddModule)(const char *); + static int (*py3_PyErr_BadArgument)(void); + static PyTypeObject* py3_PyType_Type; + static PyObject* (*py3_PyErr_Occurred)(void); + static PyObject* (*py3_PyModule_GetDict)(PyObject *); + static int (*py3_PyList_SetItem)(PyObject *, Py_ssize_t, PyObject *); + static PyObject* (*py3_PyDict_GetItemString)(PyObject *, const char *); ++ static int (*py3_PyDict_Next)(PyObject *, Py_ssize_t *, PyObject **, PyObject **); + static PyObject* (*py3_PyLong_FromLong)(long); + static PyObject* (*py3_PyDict_New)(void); ++ static PyObject* (*py3_PyIter_Next)(PyObject *); ++ static PyObject* (*py3_PyObject_GetIter)(PyObject *); + static PyObject* (*py3_Py_BuildValue)(char *, ...); + static int (*py3_PyType_Ready)(PyTypeObject *type); + static int (*py3_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item); +*************** +*** 224,244 **** +--- 259,287 ---- + static int (*py3_PyArg_Parse)(PyObject *, char *, ...); + static int (*py3_PyArg_ParseTuple)(PyObject *, char *, ...); + static int (*py3_PyMem_Free)(void *); ++ static void* (*py3_PyMem_Malloc)(size_t); + static int (*py3_Py_IsInitialized)(void); + static void (*py3_PyErr_Clear)(void); + static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *); ++ static iternextfunc py3__PyObject_NextNotImplemented; + static PyObject* py3__Py_NoneStruct; + static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o); + static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void)); + static char* (*py3__PyUnicode_AsString)(PyObject *unicode); + static PyObject* (*py3_PyUnicode_AsEncodedString)(PyObject *unicode, const char* encoding, const char* errors); + static char* (*py3_PyBytes_AsString)(PyObject *bytes); ++ static PyObject* (*py3_PyBytes_FromString)(char *str); ++ static PyObject* (*py3_PyFloat_FromDouble)(double num); ++ static double (*py3_PyFloat_AsDouble)(PyObject *); + static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name); + static PyObject* (*py3_PyModule_Create2)(struct PyModuleDef* module, int module_api_version); + static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems); + static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds); + static PyTypeObject* py3_PySlice_Type; ++ static PyTypeObject* py3_PyFloat_Type; + static PyObject* (*py3_PyErr_NewException)(char *name, PyObject *base, PyObject *dict); ++ static PyObject* (*py3_PyCapsule_New)(void *, char *, PyCapsule_Destructor); ++ static void* (*py3_PyCapsule_GetPointer)(PyObject *, char *); + # ifdef Py_DEBUG + static void (*py3__Py_NegativeRefcount)(const char *fname, int lineno, PyObject *op); + static Py_ssize_t* py3__Py_RefTotal; +*************** +*** 249,254 **** +--- 292,298 ---- + static void (*py3_PyObject_Free)(void*); + static void* (*py3_PyObject_Malloc)(size_t); + # endif ++ static int (*py3_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *); + + static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */ + +*************** +*** 280,304 **** +--- 324,361 ---- + {"Py_Initialize", (PYTHON_PROC*)&py3_Py_Initialize}, + {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple}, + {"PyMem_Free", (PYTHON_PROC*)&py3_PyMem_Free}, ++ {"PyMem_Malloc", (PYTHON_PROC*)&py3_PyMem_Malloc}, + {"PyList_New", (PYTHON_PROC*)&py3_PyList_New}, + {"PyGILState_Ensure", (PYTHON_PROC*)&py3_PyGILState_Ensure}, + {"PyGILState_Release", (PYTHON_PROC*)&py3_PyGILState_Release}, + {"PySys_SetObject", (PYTHON_PROC*)&py3_PySys_SetObject}, + {"PyList_Append", (PYTHON_PROC*)&py3_PyList_Append}, + {"PyList_Size", (PYTHON_PROC*)&py3_PyList_Size}, ++ {"PySequence_Check", (PYTHON_PROC*)&py3_PySequence_Check}, ++ {"PySequence_Size", (PYTHON_PROC*)&py3_PySequence_Size}, ++ {"PySequence_GetItem", (PYTHON_PROC*)&py3_PySequence_GetItem}, ++ {"PyTuple_Size", (PYTHON_PROC*)&py3_PyTuple_Size}, ++ {"PyTuple_GetItem", (PYTHON_PROC*)&py3_PyTuple_GetItem}, + {"PySlice_GetIndicesEx", (PYTHON_PROC*)&py3_PySlice_GetIndicesEx}, + {"PyErr_NoMemory", (PYTHON_PROC*)&py3_PyErr_NoMemory}, + {"Py_Finalize", (PYTHON_PROC*)&py3_Py_Finalize}, + {"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString}, + {"PyRun_SimpleString", (PYTHON_PROC*)&py3_PyRun_SimpleString}, ++ {"PyRun_String", (PYTHON_PROC*)&py3_PyRun_String}, + {"PyList_GetItem", (PYTHON_PROC*)&py3_PyList_GetItem}, + {"PyImport_ImportModule", (PYTHON_PROC*)&py3_PyImport_ImportModule}, ++ {"PyImport_AddModule", (PYTHON_PROC*)&py3_PyImport_AddModule}, + {"PyErr_BadArgument", (PYTHON_PROC*)&py3_PyErr_BadArgument}, + {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type}, + {"PyErr_Occurred", (PYTHON_PROC*)&py3_PyErr_Occurred}, + {"PyModule_GetDict", (PYTHON_PROC*)&py3_PyModule_GetDict}, + {"PyList_SetItem", (PYTHON_PROC*)&py3_PyList_SetItem}, + {"PyDict_GetItemString", (PYTHON_PROC*)&py3_PyDict_GetItemString}, ++ {"PyDict_Next", (PYTHON_PROC*)&py3_PyDict_Next}, ++ {"PyMapping_Check", (PYTHON_PROC*)&py3_PyMapping_Check}, ++ {"PyMapping_Items", (PYTHON_PROC*)&py3_PyMapping_Items}, ++ {"PyIter_Next", (PYTHON_PROC*)&py3_PyIter_Next}, ++ {"PyObject_GetIter", (PYTHON_PROC*)&py3_PyObject_GetIter}, + {"PyLong_FromLong", (PYTHON_PROC*)&py3_PyLong_FromLong}, + {"PyDict_New", (PYTHON_PROC*)&py3_PyDict_New}, + {"Py_BuildValue", (PYTHON_PROC*)&py3_Py_BuildValue}, +*************** +*** 311,316 **** +--- 368,374 ---- + {"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread}, + {"PyArg_Parse", (PYTHON_PROC*)&py3_PyArg_Parse}, + {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized}, ++ {"_PyObject_NextNotImplemented", (PYTHON_PROC*)&py3__PyObject_NextNotImplemented}, + {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct}, + {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear}, + {"PyObject_Init", (PYTHON_PROC*)&py3__PyObject_Init}, +*************** +*** 318,328 **** +--- 376,390 ---- + {"PyImport_AppendInittab", (PYTHON_PROC*)&py3_PyImport_AppendInittab}, + {"_PyUnicode_AsString", (PYTHON_PROC*)&py3__PyUnicode_AsString}, + {"PyBytes_AsString", (PYTHON_PROC*)&py3_PyBytes_AsString}, ++ {"PyBytes_FromString", (PYTHON_PROC*)&py3_PyBytes_FromString}, ++ {"PyFloat_FromDouble", (PYTHON_PROC*)&py3_PyFloat_FromDouble}, ++ {"PyFloat_AsDouble", (PYTHON_PROC*)&py3_PyFloat_AsDouble}, + {"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr}, + {"PyModule_Create2", (PYTHON_PROC*)&py3_PyModule_Create2}, + {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc}, + {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew}, + {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type}, ++ {"PyFloat_Type", (PYTHON_PROC*)&py3_PyFloat_Type}, + {"PyErr_NewException", (PYTHON_PROC*)&py3_PyErr_NewException}, + # ifdef Py_DEBUG + {"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount}, +*************** +*** 334,339 **** +--- 396,404 ---- + {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc}, + {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free}, + # endif ++ {"PyType_IsSubtype", (PYTHON_PROC*)&py3_PyType_IsSubtype}, ++ {"PyCapsule_New", (PYTHON_PROC*)&py3_PyCapsule_New}, ++ {"PyCapsule_GetPointer", (PYTHON_PROC*)&py3_PyCapsule_GetPointer}, + {"", NULL}, + }; + +*************** +*** 472,482 **** +--- 537,577 ---- + + static PyTypeObject RangeType; + ++ static int py3initialised = 0; ++ ++ #define PYINITIALISED py3initialised ++ ++ /* Add conversion from PyInt? */ ++ #define DICTKEY_GET(err) \ ++ if (PyBytes_Check(keyObject)) \ ++ key = (char_u *) PyBytes_AsString(keyObject); \ ++ else if (PyUnicode_Check(keyObject)) \ ++ { \ ++ bytes = PyString_AsBytes(keyObject); \ ++ if (bytes == NULL) \ ++ return err; \ ++ key = (char_u *) PyBytes_AsString(bytes); \ ++ if (key == NULL) \ ++ return err; \ ++ } \ ++ else \ ++ { \ ++ PyErr_SetString(PyExc_TypeError, _("only string keys are allowed")); \ ++ return err; \ ++ } ++ #define DICTKEY_UNREF \ ++ if (bytes != NULL) \ ++ Py_XDECREF(bytes); ++ ++ #define DICTKEY_DECL PyObject *bytes = NULL; ++ + /* + * Include the code shared with if_python.c + */ + #include "if_py_both.h" + ++ #define PY3OBJ_DELETED(obj) (obj->ob_base.ob_refcnt<=0) ++ + static void + call_PyObject_Free(void *p) + { +*************** +*** 506,511 **** +--- 601,608 ---- + static Py_ssize_t RangeStart; + static Py_ssize_t RangeEnd; + ++ static PyObject *globals; ++ + static int PythonIO_Init(void); + static void PythonIO_Fini(void); + PyMODINIT_FUNC Py3Init_vim(void); +*************** +*** 514,521 **** + * 1. Python interpreter main program. + */ + +- static int py3initialised = 0; +- + static PyGILState_STATE pygilstate = PyGILState_UNLOCKED; + + void +--- 611,616 ---- +*************** +*** 593,598 **** +--- 688,695 ---- + + PyImport_AppendInittab("vim", Py3Init_vim); + ++ globals = PyModule_GetDict(PyImport_AddModule("__main__")); ++ + /* Remove the element from sys.path that was added because of our + * argv[0] value in Py3Init_vim(). Previously we used an empty + * string, but dependinding on the OS we then get an empty entry or +*************** +*** 629,635 **** + * External interface + */ + static void +! DoPy3Command(exarg_T *eap, const char *cmd) + { + #if defined(MACOS) && !defined(MACOS_X_UNIX) + GrafPtr oldPort; +--- 726,732 ---- + * External interface + */ + static void +! DoPy3Command(exarg_T *eap, const char *cmd, typval_T *rettv) + { + #if defined(MACOS) && !defined(MACOS_X_UNIX) + GrafPtr oldPort; +*************** +*** 649,656 **** + if (Python3_Init()) + goto theend; + +! RangeStart = eap->line1; +! RangeEnd = eap->line2; + Python_Release_Vim(); /* leave vim */ + + #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) +--- 746,761 ---- + if (Python3_Init()) + goto theend; + +! if (rettv == NULL) +! { +! RangeStart = eap->line1; +! RangeEnd = eap->line2; +! } +! else +! { +! RangeStart = (PyInt) curwin->w_cursor.lnum; +! RangeEnd = RangeStart; +! } + Python_Release_Vim(); /* leave vim */ + + #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) +*************** +*** 674,680 **** + (char *)ENC_OPT, CODEC_ERROR_HANDLER); + cmdbytes = PyUnicode_AsEncodedString(cmdstr, "utf-8", CODEC_ERROR_HANDLER); + Py_XDECREF(cmdstr); +! PyRun_SimpleString(PyBytes_AsString(cmdbytes)); + Py_XDECREF(cmdbytes); + + PyGILState_Release(pygilstate); +--- 779,802 ---- + (char *)ENC_OPT, CODEC_ERROR_HANDLER); + cmdbytes = PyUnicode_AsEncodedString(cmdstr, "utf-8", CODEC_ERROR_HANDLER); + Py_XDECREF(cmdstr); +! if (rettv == NULL) +! PyRun_SimpleString(PyBytes_AsString(cmdbytes)); +! else +! { +! PyObject *r; +! +! r = PyRun_String(PyBytes_AsString(cmdbytes), Py_eval_input, +! globals, globals); +! if (r == NULL) +! EMSG(_("E860: Eval did not return a valid python 3 object")); +! else +! { +! if (ConvertFromPyObject(r, rettv) == -1) +! EMSG(_("E861: Failed to convert returned python 3 object to vim value")); +! Py_DECREF(r); +! } +! PyErr_Clear(); +! } + Py_XDECREF(cmdbytes); + + PyGILState_Release(pygilstate); +*************** +*** 709,717 **** + if (!eap->skip) + { + if (script == NULL) +! DoPy3Command(eap, (char *)eap->arg); + else +! DoPy3Command(eap, (char *)script); + } + vim_free(script); + } +--- 831,839 ---- + if (!eap->skip) + { + if (script == NULL) +! DoPy3Command(eap, (char *)eap->arg, NULL); + else +! DoPy3Command(eap, (char *)script, NULL); + } + vim_free(script); + } +*************** +*** 772,778 **** + + + /* Execute the file */ +! DoPy3Command(eap, buffer); + } + + /****************************************************** +--- 894,900 ---- + + + /* Execute the file */ +! DoPy3Command(eap, buffer, NULL); + } + + /****************************************************** +*************** +*** 802,815 **** + if (PyUnicode_Check(nameobj)) + name = _PyUnicode_AsString(nameobj); + +! if (val == NULL) { + PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes")); + return -1; + } + + if (strcmp(name, "softspace") == 0) + { +! if (!PyLong_Check(val)) { + PyErr_SetString(PyExc_TypeError, _("softspace must be an integer")); + return -1; + } +--- 924,939 ---- + if (PyUnicode_Check(nameobj)) + name = _PyUnicode_AsString(nameobj); + +! if (val == NULL) +! { + PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes")); + return -1; + } + + if (strcmp(name, "softspace") == 0) + { +! if (!PyLong_Check(val)) +! { + PyErr_SetString(PyExc_TypeError, _("softspace must be an integer")); + return -1; + } +*************** +*** 1030,1049 **** + static PyObject * + BufferSubscript(PyObject *self, PyObject* idx) + { +! if (PyLong_Check(idx)) { + long _idx = PyLong_AsLong(idx); + return BufferItem(self,_idx); +! } else if (PySlice_Check(idx)) { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PyObject *)idx, + (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1, + &start, &stop, +! &step, &slicelen) < 0) { + return NULL; + } + return BufferSlice(self, start, stop); +! } else { + PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); + return NULL; + } +--- 1154,1178 ---- + static PyObject * + BufferSubscript(PyObject *self, PyObject* idx) + { +! if (PyLong_Check(idx)) +! { + long _idx = PyLong_AsLong(idx); + return BufferItem(self,_idx); +! } else if (PySlice_Check(idx)) +! { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PyObject *)idx, + (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1, + &start, &stop, +! &step, &slicelen) < 0) +! { + return NULL; + } + return BufferSlice(self, start, stop); +! } +! else +! { + PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); + return NULL; + } +*************** +*** 1052,1075 **** + static Py_ssize_t + BufferAsSubscript(PyObject *self, PyObject* idx, PyObject* val) + { +! if (PyLong_Check(idx)) { + long n = PyLong_AsLong(idx); + return RBAsItem((BufferObject *)(self), n, val, 1, + (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count, + NULL); +! } else if (PySlice_Check(idx)) { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PyObject *)idx, + (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1, + &start, &stop, +! &step, &slicelen) < 0) { + return -1; + } + return RBAsSlice((BufferObject *)(self), start, stop, val, 1, + (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count, + NULL); +! } else { + PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); + return -1; + } +--- 1181,1209 ---- + static Py_ssize_t + BufferAsSubscript(PyObject *self, PyObject* idx, PyObject* val) + { +! if (PyLong_Check(idx)) +! { + long n = PyLong_AsLong(idx); + return RBAsItem((BufferObject *)(self), n, val, 1, + (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count, + NULL); +! } else if (PySlice_Check(idx)) +! { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PyObject *)idx, + (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1, + &start, &stop, +! &step, &slicelen) < 0) +! { + return -1; + } + return RBAsSlice((BufferObject *)(self), start, stop, val, 1, + (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count, + NULL); +! } +! else +! { + PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); + return -1; + } +*************** +*** 1142,1161 **** + static PyObject * + RangeSubscript(PyObject *self, PyObject* idx) + { +! if (PyLong_Check(idx)) { + long _idx = PyLong_AsLong(idx); + return RangeItem(self,_idx); +! } else if (PySlice_Check(idx)) { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PyObject *)idx, + ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1, + &start, &stop, +! &step, &slicelen) < 0) { + return NULL; + } + return RangeSlice(self, start, stop); +! } else { + PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); + return NULL; + } +--- 1276,1300 ---- + static PyObject * + RangeSubscript(PyObject *self, PyObject* idx) + { +! if (PyLong_Check(idx)) +! { + long _idx = PyLong_AsLong(idx); + return RangeItem(self,_idx); +! } else if (PySlice_Check(idx)) +! { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PyObject *)idx, + ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1, + &start, &stop, +! &step, &slicelen) < 0) +! { + return NULL; + } + return RangeSlice(self, start, stop); +! } +! else +! { + PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); + return NULL; + } +*************** +*** 1164,1183 **** + static Py_ssize_t + RangeAsSubscript(PyObject *self, PyObject *idx, PyObject *val) + { +! if (PyLong_Check(idx)) { + long n = PyLong_AsLong(idx); + return RangeAsItem(self, n, val); +! } else if (PySlice_Check(idx)) { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PyObject *)idx, + ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1, + &start, &stop, +! &step, &slicelen) < 0) { + return -1; + } + return RangeAsSlice(self, start, stop, val); +! } else { + PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); + return -1; + } +--- 1303,1327 ---- + static Py_ssize_t + RangeAsSubscript(PyObject *self, PyObject *idx, PyObject *val) + { +! if (PyLong_Check(idx)) +! { + long n = PyLong_AsLong(idx); + return RangeAsItem(self, n, val); +! } else if (PySlice_Check(idx)) +! { + Py_ssize_t start, stop, step, slicelen; + + if (PySlice_GetIndicesEx((PyObject *)idx, + ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1, + &start, &stop, +! &step, &slicelen) < 0) +! { + return -1; + } + return RangeAsSlice(self, start, stop, val); +! } +! else +! { + PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); + return -1; + } +*************** +*** 1390,1395 **** +--- 1534,1680 ---- + } + } + ++ /* Dictionary object - Definitions ++ */ ++ ++ static PyInt DictionaryLength(PyObject *); ++ ++ static PyMappingMethods DictionaryAsMapping = { ++ /* mp_length */ (lenfunc) DictionaryLength, ++ /* mp_subscript */ (binaryfunc) DictionaryItem, ++ /* mp_ass_subscript */ (objobjargproc) DictionaryAssItem, ++ }; ++ ++ static PyTypeObject DictionaryType; ++ ++ static void ++ DictionaryDestructor(PyObject *self) ++ { ++ DictionaryObject *this = (DictionaryObject *)(self); ++ ++ pyll_remove(&this->ref, &lastdict); ++ dict_unref(this->dict); ++ ++ Py_TYPE(self)->tp_free((PyObject*)self); ++ } ++ ++ /* List object - Definitions ++ */ ++ ++ static PyInt ListLength(PyObject *); ++ static PyObject *ListItem(PyObject *, Py_ssize_t); ++ ++ static PySequenceMethods ListAsSeq = { ++ (lenfunc) ListLength, /* sq_length, len(x) */ ++ (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */ ++ (ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */ ++ (ssizeargfunc) ListItem, /* sq_item, x[i] */ ++ (void *) 0, /* was_sq_slice, x[i:j] */ ++ (ssizeobjargproc) ListAssItem, /* sq_as_item, x[i]=v */ ++ (void *) 0, /* was_sq_ass_slice, x[i:j]=v */ ++ 0, /* sq_contains */ ++ (binaryfunc) ListConcatInPlace,/* sq_inplace_concat */ ++ 0, /* sq_inplace_repeat */ ++ }; ++ ++ static PyObject *ListSubscript(PyObject *, PyObject *); ++ static Py_ssize_t ListAsSubscript(PyObject *, PyObject *, PyObject *); ++ ++ static PyMappingMethods ListAsMapping = { ++ /* mp_length */ (lenfunc) ListLength, ++ /* mp_subscript */ (binaryfunc) ListSubscript, ++ /* mp_ass_subscript */ (objobjargproc) ListAsSubscript, ++ }; ++ ++ static PyTypeObject ListType; ++ ++ static PyObject * ++ ListSubscript(PyObject *self, PyObject* idxObject) ++ { ++ if (PyLong_Check(idxObject)) ++ { ++ long idx = PyLong_AsLong(idxObject); ++ return ListItem(self, idx); ++ } ++ else if (PySlice_Check(idxObject)) ++ { ++ Py_ssize_t start, stop, step, slicelen; ++ ++ if (PySlice_GetIndicesEx(idxObject, ListLength(self), &start, &stop, ++ &step, &slicelen) < 0) ++ return NULL; ++ return ListSlice(self, start, stop); ++ } ++ else ++ { ++ PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); ++ return NULL; ++ } ++ } ++ ++ static Py_ssize_t ++ ListAsSubscript(PyObject *self, PyObject *idxObject, PyObject *obj) ++ { ++ if (PyLong_Check(idxObject)) ++ { ++ long idx = PyLong_AsLong(idxObject); ++ return ListAssItem(self, idx, obj); ++ } ++ else if (PySlice_Check(idxObject)) ++ { ++ Py_ssize_t start, stop, step, slicelen; ++ ++ if (PySlice_GetIndicesEx(idxObject, ListLength(self), &start, &stop, ++ &step, &slicelen) < 0) ++ return -1; ++ return ListAssSlice(self, start, stop, obj); ++ } ++ else ++ { ++ PyErr_SetString(PyExc_IndexError, "Index must be int or slice"); ++ return -1; ++ } ++ } ++ ++ static void ++ ListDestructor(PyObject *self) ++ { ++ ListObject *this = (ListObject *)(self); ++ ++ pyll_remove(&this->ref, &lastlist); ++ list_unref(this->list); ++ ++ Py_TYPE(self)->tp_free((PyObject*)self); ++ } ++ ++ /* Function object - Definitions ++ */ ++ ++ static void ++ FunctionDestructor(PyObject *self) ++ { ++ FunctionObject *this = (FunctionObject *) (self); ++ ++ func_unref(this->name); ++ PyMem_Del(this->name); ++ ++ Py_TYPE(self)->tp_free((PyObject*)self); ++ } ++ ++ static PyObject * ++ FunctionGetattro(PyObject *self, PyObject *nameobj) ++ { ++ FunctionObject *this = (FunctionObject *)(self); ++ char *name = ""; ++ if (PyUnicode_Check(nameobj)) ++ name = _PyUnicode_AsString(nameobj); ++ ++ if (strcmp(name, "name") == 0) ++ return PyUnicode_FromString((char *)(this->name)); ++ ++ return PyObject_GenericGetAttr(self, nameobj); ++ } ++ + /* External interface + */ + +*************** +*** 1449,1454 **** +--- 1734,1742 ---- + PyType_Ready(&BufListType); + PyType_Ready(&WinListType); + PyType_Ready(&CurrentType); ++ PyType_Ready(&DictionaryType); ++ PyType_Ready(&ListType); ++ PyType_Ready(&FunctionType); + + /* Set sys.argv[] to avoid a crash in warn(). */ + PySys_SetArgv(1, argv); +*************** +*** 1517,1522 **** +--- 1805,1828 ---- + return result; + } + ++ void ++ do_py3eval (char_u *str, typval_T *rettv) ++ { ++ DoPy3Command(NULL, (char *) str, rettv); ++ switch(rettv->v_type) ++ { ++ case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break; ++ case VAR_LIST: ++rettv->vval.v_list->lv_refcount; break; ++ case VAR_FUNC: func_ref(rettv->vval.v_string); break; ++ } ++ } ++ ++ void ++ set_ref_in_python3 (int copyID) ++ { ++ set_ref_in_py(copyID); ++ } ++ + static void + init_structs(void) + { +*************** +*** 1598,1603 **** +--- 1904,1938 ---- + CurrentType.tp_flags = Py_TPFLAGS_DEFAULT; + CurrentType.tp_doc = "vim current object"; + ++ vim_memset(&DictionaryType, 0, sizeof(DictionaryType)); ++ DictionaryType.tp_name = "vim.dictionary"; ++ DictionaryType.tp_basicsize = sizeof(DictionaryObject); ++ DictionaryType.tp_dealloc = DictionaryDestructor; ++ DictionaryType.tp_as_mapping = &DictionaryAsMapping; ++ DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT; ++ DictionaryType.tp_doc = "dictionary pushing modifications to vim structure"; ++ DictionaryType.tp_methods = DictionaryMethods; ++ ++ vim_memset(&ListType, 0, sizeof(ListType)); ++ ListType.tp_name = "vim.list"; ++ ListType.tp_dealloc = ListDestructor; ++ ListType.tp_basicsize = sizeof(ListObject); ++ ListType.tp_as_sequence = &ListAsSeq; ++ ListType.tp_as_mapping = &ListAsMapping; ++ ListType.tp_flags = Py_TPFLAGS_DEFAULT; ++ ListType.tp_doc = "list pushing modifications to vim structure"; ++ ListType.tp_methods = ListMethods; ++ ++ vim_memset(&FunctionType, 0, sizeof(FunctionType)); ++ FunctionType.tp_name = "vim.list"; ++ FunctionType.tp_basicsize = sizeof(FunctionObject); ++ FunctionType.tp_getattro = FunctionGetattro; ++ FunctionType.tp_dealloc = FunctionDestructor; ++ FunctionType.tp_call = FunctionCall; ++ FunctionType.tp_flags = Py_TPFLAGS_DEFAULT; ++ FunctionType.tp_doc = "object that calls vim function"; ++ FunctionType.tp_methods = FunctionMethods; ++ + vim_memset(&vimmodule, 0, sizeof(vimmodule)); + vimmodule.m_name = "vim"; + vimmodule.m_doc = vim_module_doc; +*** ../vim-7.3.568/src/proto/eval.pro 2011-09-14 16:52:02.000000000 +0200 +--- src/proto/eval.pro 2012-06-20 18:20:28.000000000 +0200 +*************** +*** 46,57 **** +--- 46,66 ---- + list_T *list_alloc __ARGS((void)); + void list_unref __ARGS((list_T *l)); + void list_free __ARGS((list_T *l, int recurse)); ++ listitem_T *listitem_alloc __ARGS((void)); ++ void listitem_remove __ARGS((list_T *l, listitem_T *item)); + dictitem_T *dict_lookup __ARGS((hashitem_T *hi)); ++ listitem_T *list_find __ARGS((list_T *l, long n)); + char_u *list_find_str __ARGS((list_T *l, long idx)); ++ void list_append __ARGS((list_T *l, listitem_T *item)); + int list_append_tv __ARGS((list_T *l, typval_T *tv)); + int list_append_dict __ARGS((list_T *list, dict_T *dict)); + int list_append_string __ARGS((list_T *l, char_u *str, int len)); ++ int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); ++ void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); + int garbage_collect __ARGS((void)); ++ void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID)); ++ void set_ref_in_list __ARGS((list_T *l, int copyID)); ++ void set_ref_in_item __ARGS((typval_T *tv, int copyID)); + dict_T *dict_alloc __ARGS((void)); + void dict_unref __ARGS((dict_T *d)); + dictitem_T *dictitem_alloc __ARGS((char_u *key)); +*************** +*** 64,69 **** +--- 73,79 ---- + long get_dict_number __ARGS((dict_T *d, char_u *key)); + char_u *get_function_name __ARGS((expand_T *xp, int idx)); + char_u *get_expr_name __ARGS((expand_T *xp, int idx)); ++ int func_call __ARGS((char_u *name, typval_T *args, dict_T *selfdict, typval_T *rettv)); + long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit)); + void set_vim_var_nr __ARGS((int idx, long val)); + long get_vim_var_nr __ARGS((int idx)); +*************** +*** 94,99 **** +--- 104,111 ---- + void func_dump_profile __ARGS((FILE *fd)); + char_u *get_user_func_name __ARGS((expand_T *xp, int idx)); + void ex_delfunction __ARGS((exarg_T *eap)); ++ void func_unref __ARGS((char_u *name)); ++ void func_ref __ARGS((char_u *name)); + void ex_return __ARGS((exarg_T *eap)); + int do_return __ARGS((exarg_T *eap, int reanimate, int is_cmd, void *rettv)); + void discard_pending_return __ARGS((void *rettv)); +*** ../vim-7.3.568/src/proto/if_python.pro 2010-08-15 21:57:28.000000000 +0200 +--- src/proto/if_python.pro 2012-06-20 18:23:06.000000000 +0200 +*************** +*** 6,9 **** +--- 6,11 ---- + void ex_pyfile __ARGS((exarg_T *eap)); + void python_buffer_free __ARGS((buf_T *buf)); + void python_window_free __ARGS((win_T *win)); ++ void do_pyeval __ARGS((char_u *str, typval_T *rettv)); ++ void set_ref_in_python __ARGS((int copyID)); + /* vim: set ft=c : */ +*** ../vim-7.3.568/src/proto/if_python3.pro 2010-08-15 21:57:28.000000000 +0200 +--- src/proto/if_python3.pro 2012-06-20 18:34:26.000000000 +0200 +*************** +*** 6,9 **** +--- 6,11 ---- + void ex_py3file __ARGS((exarg_T *eap)); + void python3_buffer_free __ARGS((buf_T *buf)); + void python3_window_free __ARGS((win_T *win)); ++ void do_py3eval __ARGS((char_u *str, typval_T *rettv)); ++ void set_ref_in_python3 __ARGS((int copyID)); + /* vim: set ft=c : */ +*** ../vim-7.3.568/src/testdir/Make_amiga.mak 2012-04-05 16:56:38.000000000 +0200 +--- src/testdir/Make_amiga.mak 2012-06-20 18:43:05.000000000 +0200 +*************** +*** 14,19 **** +--- 14,20 ---- + # test27 can't edit file with "*" + # test52 only for Win32 + # test85 no Lua interface ++ # test86, 87 no Python interface + + SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ + test7.out test8.out test9.out \ +*** ../vim-7.3.568/src/testdir/Make_dos.mak 2012-04-13 19:11:16.000000000 +0200 +--- src/testdir/Make_dos.mak 2012-06-20 18:43:45.000000000 +0200 +*************** +*** 30,36 **** + test68.out test69.out test71.out test72.out test73.out \ + test74.out test75.out test76.out test77.out test78.out \ + test79.out test80.out test81.out test82.out test83.out \ +! test84.out test85.out + + SCRIPTS32 = test50.out test70.out + +--- 30,36 ---- + test68.out test69.out test71.out test72.out test73.out \ + test74.out test75.out test76.out test77.out test78.out \ + test79.out test80.out test81.out test82.out test83.out \ +! test84.out test85.out test86.out test87.out + + SCRIPTS32 = test50.out test70.out + +*** ../vim-7.3.568/src/testdir/Make_ming.mak 2012-04-13 19:11:16.000000000 +0200 +--- src/testdir/Make_ming.mak 2012-06-20 18:44:12.000000000 +0200 +*************** +*** 50,56 **** + test68.out test69.out test71.out test72.out test73.out \ + test74.out test75.out test76.out test77.out test78.out \ + test79.out test80.out test81.out test82.out test83.out \ +! test84.out test85.out + + SCRIPTS32 = test50.out test70.out + +--- 50,56 ---- + test68.out test69.out test71.out test72.out test73.out \ + test74.out test75.out test76.out test77.out test78.out \ + test79.out test80.out test81.out test82.out test83.out \ +! test84.out test85.out test86.out test87.out + + SCRIPTS32 = test50.out test70.out + +*** ../vim-7.3.568/src/testdir/Make_os2.mak 2012-04-05 16:56:38.000000000 +0200 +--- src/testdir/Make_os2.mak 2012-06-20 18:44:32.000000000 +0200 +*************** +*** 14,19 **** +--- 14,20 ---- + # test27 can't edit file with "*" in file name + # test52 only for Win32 + # test85 no Lua interface ++ # test86, 87 no Python interface + + SCRIPTS = test1.out test3.out test4.out test5.out test6.out \ + test7.out test8.out test9.out \ +*** ../vim-7.3.568/src/testdir/Makefile 2012-04-05 16:56:38.000000000 +0200 +--- src/testdir/Makefile 2012-06-29 11:56:00.000000000 +0200 +*************** +*** 27,33 **** + test69.out test70.out test71.out test72.out test73.out \ + test74.out test75.out test76.out test77.out test78.out \ + test79.out test80.out test81.out test82.out test83.out \ +! test84.out test85.out + + SCRIPTS_GUI = test16.out + +--- 27,33 ---- + test69.out test70.out test71.out test72.out test73.out \ + test74.out test75.out test76.out test77.out test78.out \ + test79.out test80.out test81.out test82.out test83.out \ +! test84.out test85.out test86.out test87.out + + SCRIPTS_GUI = test16.out + +*** ../vim-7.3.568/src/testdir/test86.in 2012-06-20 20:19:31.000000000 +0200 +--- src/testdir/test86.in 2012-06-20 18:01:02.000000000 +0200 +*************** +*** 0 **** +--- 1,211 ---- ++ Tests for various python features. vim: set ft=vim : ++ ++ STARTTEST ++ :so small.vim ++ :if !has('python') | e! test.ok | wq! test.out | endif ++ :py import vim ++ :fun Test() ++ :let l = [] ++ :py l=vim.bindeval('l') ++ :py f=vim.bindeval('function("strlen")') ++ :" Extending List directly with different types ++ :py l.extend([1, "as'd", [1, 2, f, {'a': 1}]]) ++ :$put =string(l) ++ :$put =string(l[-1]) ++ :try ++ : $put =string(l[-4]) ++ :catch ++ : $put =v:exception[:13] ++ :endtry ++ :" List assignment ++ :py l[0]=0 ++ :$put =string(l) ++ :py l[-2]=f ++ :$put =string(l) ++ :" ++ :" Extending Dictionary directly with different types ++ :let d = {} ++ :py d=vim.bindeval('d') ++ :py d['1']='asd' ++ :py d['b']=[1, 2, f] ++ :py d['-1']={'a': 1} ++ :let dkeys = [] ++ :py dk=vim.bindeval('dkeys') ++ :py dkeys=d.keys() ++ :py dkeys.sort() ++ :py dk.extend(dkeys) ++ :$put =string(dkeys) ++ :for [key, val] in sort(items(d)) ++ : $put =string(key) . ' : ' . string(val) ++ : unlet key val ++ :endfor ++ :" ++ :" removing items with del ++ :py del l[2] ++ :$put =string(l) ++ :let l = range(8) ++ :py l=vim.bindeval('l') ++ :try ++ : py del l[:3] ++ : py del l[1:] ++ :catch ++ : $put =v:exception ++ :endtry ++ :$put =string(l) ++ :" ++ :py del d['-1'] ++ :$put =string(d) ++ :" ++ :" removing items out of range: silently skip items that don't exist ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :" The following two ranges delete nothing as they match empty list: ++ :py del l[2:1] ++ :$put =string(l) ++ :py del l[2:2] ++ :$put =string(l) ++ :py del l[2:3] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py del l[2:4] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py del l[2:5] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py del l[2:6] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :" The following two ranges delete nothing as they match empty list: ++ :py del l[-1:2] ++ :$put =string(l) ++ :py del l[-2:2] ++ :$put =string(l) ++ :py del l[-3:2] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py del l[-4:2] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py del l[-5:2] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py del l[-6:2] ++ :$put =string(l) ++ :" ++ :" Slice assignment to a list ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py l[0:0]=['a'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py l[1:2]=['b'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py l[2:4]=['c'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py l[4:4]=['d'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py l[-1:2]=['e'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py l[-10:2]=['f'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :py l[2:-10]=['g'] ++ :$put =string(l) ++ :let l = [] ++ :py l=vim.bindeval('l') ++ :py l[0:0]=['h'] ++ :$put =string(l) ++ :" ++ :" Locked variables ++ :let l = [0, 1, 2, 3] ++ :py l=vim.bindeval('l') ++ :lockvar! l ++ :py l[2]='i' ++ :$put =string(l) ++ :unlockvar! l ++ :" ++ :" Function calls ++ :function New(...) ++ :return ['NewStart']+a:000+['NewEnd'] ++ :endfunction ++ :function DictNew(...) dict ++ :return ['DictNewStart']+a:000+['DictNewEnd', self] ++ :endfunction ++ :let l=[function('New'), function('DictNew')] ++ :py l=vim.bindeval('l') ++ :py l.extend(list(l[0](1, 2, 3))) ++ :$put =string(l) ++ :py l.extend(list(l[1](1, 2, 3, self={'a': 'b'}))) ++ :$put =string(l) ++ :py l.extend([l[0].name]) ++ :$put =string(l) ++ :try ++ : py l[1](1, 2, 3) ++ :catch ++ : $put =v:exception[:16] ++ :endtry ++ :delfunction New ++ :try ++ : py l[0](1, 2, 3) ++ :catch ++ : $put =v:exception[:16] ++ :endtry ++ :if has('float') ++ : let l=[0.0] ++ : py l=vim.bindeval('l') ++ : py l.extend([0.0]) ++ : $put =string(l) ++ :else ++ : $put ='[0.0, 0.0]' ++ :endif ++ :" ++ :" pyeval() ++ :let l=pyeval('range(3)') ++ :$put =string(l) ++ :let d=pyeval('{"a": "b", "c": 1, "d": ["e"]}') ++ :$put =sort(items(d)) ++ :try ++ : let undef=pyeval('undefined_name') ++ :catch ++ : $put =v:exception[:13] ++ :endtry ++ :try ++ : let vim=pyeval('vim') ++ :catch ++ : $put =v:exception[:13] ++ :endtry ++ :if has('float') ++ : let f=pyeval('0.0') ++ : $put =string(f) ++ :else ++ : $put ='0.0' ++ :endif ++ :endfun ++ :" ++ :call Test() ++ :" ++ :delfunc Test ++ :call garbagecollect(1) ++ :" ++ :/^start:/,$wq! test.out ++ ENDTEST ++ ++ start: +*** ../vim-7.3.568/src/testdir/test86.ok 2012-06-20 20:19:31.000000000 +0200 +--- src/testdir/test86.ok 2012-06-20 18:01:02.000000000 +0200 +*************** +*** 0 **** +--- 1,47 ---- ++ start: ++ [1, 'as''d', [1, 2, function('strlen'), {'a': 1}]] ++ [1, 2, function('strlen'), {'a': 1}] ++ Vim(put):E684: ++ [0, 'as''d', [1, 2, function('strlen'), {'a': 1}]] ++ [0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]] ++ ['-1', '1', 'b'] ++ '-1' : {'a': 1} ++ '1' : 'asd' ++ 'b' : [1, 2, function('strlen')] ++ [0, function('strlen')] ++ [3] ++ {'1': 'asd', 'b': [1, 2, function('strlen')]} ++ [0, 1, 2, 3] ++ [0, 1, 2, 3] ++ [0, 1, 3] ++ [0, 1] ++ [0, 1] ++ [0, 1] ++ [0, 1, 2, 3] ++ [0, 1, 2, 3] ++ [0, 2, 3] ++ [2, 3] ++ [2, 3] ++ [2, 3] ++ ['a', 0, 1, 2, 3] ++ [0, 'b', 2, 3] ++ [0, 1, 'c'] ++ [0, 1, 2, 3, 'd'] ++ [0, 1, 2, 'e', 3] ++ ['f', 2, 3] ++ [0, 1, 'g', 2, 3] ++ ['h'] ++ [0, 1, 2, 3] ++ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] ++ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] ++ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New'] ++ Vim(python):E725: ++ Vim(python):E117: ++ [0.0, 0.0] ++ [0, 1, 2] ++ ['a', 'b'] ++ ['c', 1] ++ ['d', ['e']] ++ Vim(let):E858: ++ Vim(let):E859: ++ 0.0 +*** ../vim-7.3.568/src/testdir/test87.in 2012-06-20 20:19:31.000000000 +0200 +--- src/testdir/test87.in 2012-06-20 18:01:02.000000000 +0200 +*************** +*** 0 **** +--- 1,211 ---- ++ Tests for various python features. vim: set ft=vim : ++ ++ STARTTEST ++ :so small.vim ++ :if !has('python3') | e! test.ok | wq! test.out | endif ++ :py3 import vim ++ :fun Test() ++ :let l = [] ++ :py3 l=vim.bindeval('l') ++ :py3 f=vim.bindeval('function("strlen")') ++ :" Extending List directly with different types ++ :py3 l+=[1, "as'd", [1, 2, f, {'a': 1}]] ++ :$put =string(l) ++ :$put =string(l[-1]) ++ :try ++ : $put =string(l[-4]) ++ :catch ++ : $put =v:exception[:13] ++ :endtry ++ :" List assignment ++ :py3 l[0]=0 ++ :$put =string(l) ++ :py3 l[-2]=f ++ :$put =string(l) ++ :" ++ :" Extending Dictionary directly with different types ++ :let d = {} ++ :py3 d=vim.bindeval('d') ++ :py3 d['1']='asd' ++ :py3 d['b']=[1, 2, f] ++ :py3 d['-1']={'a': 1} ++ :let dkeys = [] ++ :py3 dk=vim.bindeval('dkeys') ++ :py3 dkeys=d.keys() ++ :py3 dkeys.sort() ++ :py3 dk+=dkeys ++ :$put =string(dkeys) ++ :for [key, val] in sort(items(d)) ++ : $put =string(key) . ' : ' . string(val) ++ : unlet key val ++ :endfor ++ :" ++ :" removing items with del ++ :py3 del l[2] ++ :$put =string(l) ++ :let l = range(8) ++ :py3 l=vim.bindeval('l') ++ :try ++ : py3 del l[:3] ++ : py3 del l[1:] ++ :catch ++ : $put =v:exception ++ :endtry ++ :$put =string(l) ++ :" ++ :py3 del d['-1'] ++ :$put =string(d) ++ :" ++ :" removing items out of range: silently skip items that don't exist ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :" The following two ranges delete nothing as they match empty list: ++ :py3 del l[2:1] ++ :$put =string(l) ++ :py3 del l[2:2] ++ :$put =string(l) ++ :py3 del l[2:3] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 del l[2:4] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 del l[2:5] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 del l[2:6] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :" The following two ranges delete nothing as they match empty list: ++ :py3 del l[-1:2] ++ :$put =string(l) ++ :py3 del l[-2:2] ++ :$put =string(l) ++ :py3 del l[-3:2] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 del l[-4:2] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 del l[-5:2] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 del l[-6:2] ++ :$put =string(l) ++ :" ++ :" Slice assignment to a list ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 l[0:0]=['a'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 l[1:2]=['b'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 l[2:4]=['c'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 l[4:4]=['d'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 l[-1:2]=['e'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 l[-10:2]=['f'] ++ :$put =string(l) ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :py3 l[2:-10]=['g'] ++ :$put =string(l) ++ :let l = [] ++ :py3 l=vim.bindeval('l') ++ :py3 l[0:0]=['h'] ++ :$put =string(l) ++ :" ++ :" Locked variables ++ :let l = [0, 1, 2, 3] ++ :py3 l=vim.bindeval('l') ++ :lockvar! l ++ :py3 l[2]='i' ++ :$put =string(l) ++ :unlockvar! l ++ :" ++ :" Function calls ++ :function New(...) ++ :return ['NewStart']+a:000+['NewEnd'] ++ :endfunction ++ :function DictNew(...) dict ++ :return ['DictNewStart']+a:000+['DictNewEnd', self] ++ :endfunction ++ :let l=[function('New'), function('DictNew')] ++ :py3 l=vim.bindeval('l') ++ :py3 l.extend(list(l[0](1, 2, 3))) ++ :$put =string(l) ++ :py3 l.extend(list(l[1](1, 2, 3, self={'a': 'b'}))) ++ :$put =string(l) ++ :py3 l+=[l[0].name] ++ :$put =string(l) ++ :try ++ : py3 l[1](1, 2, 3) ++ :catch ++ : $put =v:exception[:13] ++ :endtry ++ :delfunction New ++ :try ++ : py3 l[0](1, 2, 3) ++ :catch ++ : $put =v:exception[:13] ++ :endtry ++ :if has('float') ++ : let l=[0.0] ++ : py3 l=vim.bindeval('l') ++ : py3 l.extend([0.0]) ++ : $put =string(l) ++ :else ++ : $put ='[0.0, 0.0]' ++ :endif ++ :" ++ :" py3eval() ++ :let l=py3eval('[0, 1, 2]') ++ :$put =string(l) ++ :let d=py3eval('{"a": "b", "c": 1, "d": ["e"]}') ++ :$put =sort(items(d)) ++ :try ++ : let undef=py3eval('undefined_name') ++ :catch ++ : $put =v:exception[:13] ++ :endtry ++ :try ++ : let vim=py3eval('vim') ++ :catch ++ : $put =v:exception[:13] ++ :endtry ++ :if has('float') ++ : let f=py3eval('0.0') ++ : $put =string(f) ++ :else ++ : $put ='0.0' ++ :endif ++ :endfun ++ :" ++ :call Test() ++ :" ++ :delfunc Test ++ :call garbagecollect(1) ++ :" ++ :/^start:/,$wq! test.out ++ ENDTEST ++ ++ start: +*** ../vim-7.3.568/src/testdir/test87.ok 2012-06-20 20:19:31.000000000 +0200 +--- src/testdir/test87.ok 2012-06-20 18:01:02.000000000 +0200 +*************** +*** 0 **** +--- 1,47 ---- ++ start: ++ [1, 'as''d', [1, 2, function('strlen'), {'a': 1}]] ++ [1, 2, function('strlen'), {'a': 1}] ++ Vim(put):E684: ++ [0, 'as''d', [1, 2, function('strlen'), {'a': 1}]] ++ [0, function('strlen'), [1, 2, function('strlen'), {'a': 1}]] ++ ['-1', '1', 'b'] ++ '-1' : {'a': 1} ++ '1' : 'asd' ++ 'b' : [1, 2, function('strlen')] ++ [0, function('strlen')] ++ [3] ++ {'1': 'asd', 'b': [1, 2, function('strlen')]} ++ [0, 1, 2, 3] ++ [0, 1, 2, 3] ++ [0, 1, 3] ++ [0, 1] ++ [0, 1] ++ [0, 1] ++ [0, 1, 2, 3] ++ [0, 1, 2, 3] ++ [0, 2, 3] ++ [2, 3] ++ [2, 3] ++ [2, 3] ++ ['a', 0, 1, 2, 3] ++ [0, 'b', 2, 3] ++ [0, 1, 'c'] ++ [0, 1, 2, 3, 'd'] ++ [0, 1, 2, 'e', 3] ++ ['f', 2, 3] ++ [0, 1, 'g', 2, 3] ++ ['h'] ++ [0, 1, 2, 3] ++ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] ++ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] ++ [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}, 'New'] ++ Vim(py3):E725: ++ Vim(py3):E117: ++ [0.0, 0.0] ++ [0, 1, 2] ++ ['a', 'b'] ++ ['c', 1] ++ ['d', ['e']] ++ Vim(let):E860: ++ Vim(let):E861: ++ 0.0 +*** ../vim-7.3.568/src/version.c 2012-06-29 12:35:40.000000000 +0200 +--- src/version.c 2012-06-29 12:47:03.000000000 +0200 +*************** +*** 716,717 **** +--- 716,719 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 569, + /**/ + +-- +hundred-and-one symptoms of being an internet addict: +69. Yahoo welcomes you with your own start page + + /// 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 ///