aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-08-18 05:09:24 +0800
committerzeertzjq <zeertzjq@outlook.com>2023-08-18 05:29:05 +0800
commitbb29ef40084e1cea1f35cbbcbac794f41f46d5f8 (patch)
tree4d6b898cb67d3d1aec5d3cd49acdb0be7be07ada /src/nvim/eval.c
parentffb87f4dd992ff23ff66f888dbe1bcc54bd0b012 (diff)
downloadrneovim-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.c36
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) {