summaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-10-30 21:48:41 +0100
committerBram Moolenaar <Bram@vim.org>2017-10-30 21:48:41 +0100
commit48570488f17e397183ea7d5c7ca67d6e4ffb013d (patch)
treef9bbc935f2f0d999e16d047056c747168791cb3e /src/eval.c
parent2e51d9a0972080b087d566608472928d5b7b35d7 (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.c99
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 */