diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-08-18 05:09:24 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-08-18 05:29:05 +0800 |
commit | bb29ef40084e1cea1f35cbbcbac794f41f46d5f8 (patch) | |
tree | 4d6b898cb67d3d1aec5d3cd49acdb0be7be07ada /src/nvim/eval.c | |
parent | ffb87f4dd992ff23ff66f888dbe1bcc54bd0b012 (diff) | |
download | rneovim-bb29ef40084e1cea1f35cbbcbac794f41f46d5f8.tar.gz rneovim-bb29ef40084e1cea1f35cbbcbac794f41f46d5f8.tar.bz2 rneovim-bb29ef40084e1cea1f35cbbcbac794f41f46d5f8.zip |
vim-patch:9.0.1723: Fix regression in {func} argument of reduce()
Problem: Fix regression in {func} argument of reduce()
Solution: pass function name as string again
Before patch 9.0.0548, passing a string as {func} argument of reduce()
is treated as a function name, but after patch 9.0.0548 it is treated as
an expression instead, which is useless as reduce() doesn't set any v:
variables. This PR restores the behavior of {func} before that patch.
Also correct an emsg() call, as e_string_list_or_blob_required doesn't
contain format specifiers.
closes: vim/vim#12824
https://github.com/vim/vim/commit/ad0c442f1fcc6fe9c433777ee3e5b9e6addc6d69
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r-- | src/nvim/eval.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 9baf3209a2..08c5ef743b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -820,36 +820,44 @@ bool eval_expr_valid_arg(const typval_T *const tv) && (tv->v_type != VAR_STRING || (tv->vval.v_string != NULL && *tv->vval.v_string != NUL)); } -int eval_expr_typval(const typval_T *expr, typval_T *argv, int argc, typval_T *rettv) - FUNC_ATTR_NONNULL_ARG(1, 2, 4) +/// Evaluate an expression, which can be a function, partial or string. +/// Pass arguments "argv[argc]". +/// Return the result in "rettv" and OK or FAIL. +/// +/// @param want_func if true, treat a string as a function name, not an expression +int eval_expr_typval(const typval_T *expr, bool want_func, typval_T *argv, int argc, + typval_T *rettv) + FUNC_ATTR_NONNULL_ALL { + char buf[NUMBUFLEN]; funcexe_T funcexe = FUNCEXE_INIT; - if (expr->v_type == VAR_FUNC) { - const char *const s = expr->vval.v_string; + if (expr->v_type == VAR_PARTIAL) { + partial_T *const partial = expr->vval.v_partial; + if (partial == NULL) { + return FAIL; + } + const char *const s = partial_name(partial); if (s == NULL || *s == NUL) { return FAIL; } funcexe.fe_evaluate = true; + funcexe.fe_partial = partial; if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) { return FAIL; } - } else if (expr->v_type == VAR_PARTIAL) { - partial_T *const partial = expr->vval.v_partial; - if (partial == NULL) { - return FAIL; - } - const char *const s = partial_name(partial); + } else if (expr->v_type == VAR_FUNC || want_func) { + const char *const s = (expr->v_type == VAR_FUNC + ? expr->vval.v_string + : tv_get_string_buf_chk(expr, buf)); if (s == NULL || *s == NUL) { return FAIL; } funcexe.fe_evaluate = true; - funcexe.fe_partial = partial; if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) { return FAIL; } } else { - char buf[NUMBUFLEN]; char *s = (char *)tv_get_string_buf_chk(expr, buf); if (s == NULL) { return FAIL; @@ -874,7 +882,7 @@ bool eval_expr_to_bool(const typval_T *expr, bool *error) { typval_T argv, rettv; - if (eval_expr_typval(expr, &argv, 0, &rettv) == FAIL) { + if (eval_expr_typval(expr, false, &argv, 0, &rettv) == FAIL) { *error = true; return false; } @@ -5352,7 +5360,7 @@ static int filter_map_one(typval_T *tv, typval_T *expr, const filtermap_T filter tv_copy(tv, &vimvars[VV_VAL].vv_tv); argv[0] = vimvars[VV_KEY].vv_tv; argv[1] = vimvars[VV_VAL].vv_tv; - if (eval_expr_typval(expr, argv, 2, newtv) == FAIL) { + if (eval_expr_typval(expr, false, argv, 2, newtv) == FAIL) { goto theend; } if (filtermap == FILTERMAP_FILTER) { |