# HG changeset patch # User Bram Moolenaar # Date 1384140353 -3600 # Node ID 60a5b7b82016da631dd7acc6121913d02c5677f8 # Parent 3f4e943e122a87f697566402a5d1787a45d84e43 updated for version 7.4.086 Problem: Skipping over an expression when not evaluating it does not work properly for dict members. Solution: Skip over unrecognized expression. (ZyX) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -19845,24 +19845,30 @@ handle_subscript(arg, rettv, evaluate, v while (ret == OK && (**arg == '[' || (**arg == '.' && rettv->v_type == VAR_DICT) - || (**arg == '(' && rettv->v_type == VAR_FUNC)) + || (**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC))) && !vim_iswhite(*(*arg - 1))) { if (**arg == '(') { /* need to copy the funcref so that we can clear rettv */ - functv = *rettv; - rettv->v_type = VAR_UNKNOWN; - - /* Invoke the function. Recursive! */ - s = functv.vval.v_string; + if (evaluate) + { + functv = *rettv; + rettv->v_type = VAR_UNKNOWN; + + /* Invoke the function. Recursive! */ + s = functv.vval.v_string; + } + else + s = (char_u *)""; ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, curwin->w_cursor.lnum, curwin->w_cursor.lnum, &len, evaluate, selfdict); /* Clear the funcref afterwards, so that deleting it while * evaluating the arguments is possible (see test55). */ - clear_tv(&functv); + if (evaluate) + clear_tv(&functv); /* Stop the expression evaluation when immediately aborting on * error, or when an interrupt occurred or an exception was thrown diff --git a/src/testdir/test34.in b/src/testdir/test34.in --- a/src/testdir/test34.in +++ b/src/testdir/test34.in @@ -1,6 +1,7 @@ Test for user functions. Also test an mapping calling a function. Also test that a builtin function cannot be replaced. +Also test for regression when calling arbitrary expression. STARTTEST :so small.vim @@ -62,7 +63,17 @@ XX+-XX [(one again:call append(line('$'), max([1, 2, 3])) :call extend(g:, {'max': function('min')}) :call append(line('$'), max([1, 2, 3])) -:$-7,$w! test.out +:try +: " Regression: the first line below used to throw ?E110: Missing ')'? +: " Second is here just to prove that this line is correct when not skipping +: " rhs of &&. +: $put =(0&&(function('tr'))(1, 2, 3)) +: $put =(1&&(function('tr'))(1, 2, 3)) +:catch +: $put ='!!! Unexpected exception:' +: $put =v:exception +:endtry +:$-9,$w! test.out :delfunc Table :delfunc Compute :delfunc Expr1 diff --git a/src/testdir/test34.ok b/src/testdir/test34.ok --- a/src/testdir/test34.ok +++ b/src/testdir/test34.ok @@ -6,3 +6,5 @@ 2. two 1. one again 3 3 +0 +1 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -739,6 +739,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 86, +/**/ 85, /**/ 84,