Mercurial > vim
diff src/eval.c @ 12722:7749260f261c v8.0.1239
patch 8.0.1239: cannot use a lambda for the skip argument to searchpair()
commit https://github.com/vim/vim/commit/48570488f17e397183ea7d5c7ca67d6e4ffb013d
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Oct 30 21:48:41 2017 +0100
patch 8.0.1239: cannot use a lambda for the skip argument to searchpair()
Problem: Cannot use a lambda for the skip argument to searchpair().
Solution: Evaluate a partial, funcref and lambda. (LemonBoy, closes https://github.com/vim/vim/issues/1454,
closes #2265)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 30 Oct 2017 22:00:05 +0100 |
parents | e769c912fcd9 |
children | 9c1659761fc3 |
line wrap: on
line diff
--- a/src/eval.c +++ b/src/eval.c @@ -696,6 +696,70 @@ eval_to_bool( return (int)retval; } + static int +eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv) +{ + char_u *s; + int dummy; + char_u buf[NUMBUFLEN]; + + if (expr->v_type == VAR_FUNC) + { + s = expr->vval.v_string; + if (s == NULL || *s == NUL) + return FAIL; + if (call_func(s, (int)STRLEN(s), rettv, argc, argv, NULL, + 0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL) + return FAIL; + } + else if (expr->v_type == VAR_PARTIAL) + { + partial_T *partial = expr->vval.v_partial; + + s = partial_name(partial); + if (s == NULL || *s == NUL) + return FAIL; + if (call_func(s, (int)STRLEN(s), rettv, argc, argv, NULL, + 0L, 0L, &dummy, TRUE, partial, NULL) == FAIL) + return FAIL; + } + else + { + s = get_tv_string_buf_chk(expr, buf); + if (s == NULL) + return FAIL; + s = skipwhite(s); + if (eval1(&s, rettv, TRUE) == FAIL) + return FAIL; + if (*s != NUL) /* check for trailing chars after expr */ + { + EMSG2(_(e_invexpr2), s); + return FAIL; + } + } + return OK; +} + +/* + * Like eval_to_bool() but using a typval_T instead of a string. + * Works for string, funcref and partial. + */ + int +eval_expr_to_bool(typval_T *expr, int *error) +{ + typval_T rettv; + int res; + + if (eval_expr_typval(expr, NULL, 0, &rettv) == FAIL) + { + *error = TRUE; + return FALSE; + } + res = (get_tv_number_chk(&rettv, error) != 0); + clear_tv(&rettv); + return res; +} + /* * Top level evaluation function, returning a string. If "skip" is TRUE, * only parsing to "nextcmd" is done, without reporting errors. Return @@ -9971,44 +10035,13 @@ filter_map_one(typval_T *tv, typval_T *e { typval_T rettv; typval_T argv[3]; - char_u buf[NUMBUFLEN]; - char_u *s; int retval = FAIL; - int dummy; copy_tv(tv, &vimvars[VV_VAL].vv_tv); argv[0] = vimvars[VV_KEY].vv_tv; argv[1] = vimvars[VV_VAL].vv_tv; - if (expr->v_type == VAR_FUNC) - { - s = expr->vval.v_string; - if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL, - 0L, 0L, &dummy, TRUE, NULL, NULL) == FAIL) - goto theend; - } - else if (expr->v_type == VAR_PARTIAL) - { - partial_T *partial = expr->vval.v_partial; - - s = partial_name(partial); - if (call_func(s, (int)STRLEN(s), &rettv, 2, argv, NULL, - 0L, 0L, &dummy, TRUE, partial, NULL) == FAIL) - goto theend; - } - else - { - s = get_tv_string_buf_chk(expr, buf); - if (s == NULL) - goto theend; - s = skipwhite(s); - if (eval1(&s, &rettv, TRUE) == FAIL) - goto theend; - if (*s != NUL) /* check for trailing chars after expr */ - { - EMSG2(_(e_invexpr2), s); - goto theend; - } - } + if (eval_expr_typval(expr, argv, 2, &rettv) == FAIL) + goto theend; if (map) { /* map(): replace the list item value */