diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-10-30 21:48:41 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-10-30 21:48:41 +0100 |
commit | 48570488f17e397183ea7d5c7ca67d6e4ffb013d (patch) | |
tree | f9bbc935f2f0d999e16d047056c747168791cb3e /src/eval.c | |
parent | 2e51d9a0972080b087d566608472928d5b7b35d7 (diff) |
patch 8.0.1239: cannot use a lambda for the skip argument to searchpair()v8.0.1239
Problem: Cannot use a lambda for the skip argument to searchpair().
Solution: Evaluate a partial, funcref and lambda. (LemonBoy, closes #1454,
closes #2265)
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 99 |
1 files changed, 66 insertions, 33 deletions
diff --git a/src/eval.c b/src/eval.c index 8cb91e783d..e8a1b0aa35 100644 --- 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 *expr, int map, int *remp) { 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 */ |