diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-08-17 22:15:47 +0200 |
---|---|---|
committer | Christian Brabandt <cb@256bit.org> | 2023-08-17 22:15:47 +0200 |
commit | ad0c442f1fcc6fe9c433777ee3e5b9e6addc6d69 (patch) | |
tree | 60279c75b0d60c44f602a980717db10239fcbbe4 /src | |
parent | 4f389e7c0fe7dfeccfa512a72fa36f9028d57159 (diff) |
patch 9.0.1723: Fix regression in {func} argument of reduce()v9.0.1723
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: #12824
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/blob.c | 2 | ||||
-rw-r--r-- | src/eval.c | 28 | ||||
-rw-r--r-- | src/evalfunc.c | 2 | ||||
-rw-r--r-- | src/filepath.c | 2 | ||||
-rw-r--r-- | src/list.c | 6 | ||||
-rw-r--r-- | src/proto/eval.pro | 2 | ||||
-rw-r--r-- | src/strings.c | 2 | ||||
-rw-r--r-- | src/testdir/test_listdict.vim | 6 | ||||
-rw-r--r-- | src/version.c | 2 |
9 files changed, 31 insertions, 21 deletions
diff --git a/src/blob.c b/src/blob.c index 9b409f614e..c5d7eaed64 100644 --- a/src/blob.c +++ b/src/blob.c @@ -769,7 +769,7 @@ blob_reduce( argv[1].v_type = VAR_NUMBER; argv[1].vval.v_number = blob_get(b, i); - r = eval_expr_typval(expr, argv, 2, NULL, rettv); + r = eval_expr_typval(expr, TRUE, argv, 2, NULL, rettv); clear_tv(&argv[0]); if (r == FAIL || called_emsg != called_emsg_start) diff --git a/src/eval.c b/src/eval.c index 8660a25d50..cfcec9bac0 100644 --- a/src/eval.c +++ b/src/eval.c @@ -252,12 +252,14 @@ eval_expr_get_funccal(typval_T *expr, typval_T *rettv) /* * Evaluate an expression, which can be a function, partial or string. * Pass arguments "argv[argc]". + * If "want_func" is TRUE treat a string as a function name, not an expression. * "fc_arg" is from eval_expr_get_funccal() or NULL; * Return the result in "rettv" and OK or FAIL. */ int eval_expr_typval( typval_T *expr, + int want_func, typval_T *argv, int argc, funccall_T *fc_arg, @@ -267,17 +269,7 @@ eval_expr_typval( char_u buf[NUMBUFLEN]; funcexe_T funcexe; - if (expr->v_type == VAR_FUNC) - { - s = expr->vval.v_string; - if (s == NULL || *s == NUL) - return FAIL; - CLEAR_FIELD(funcexe); - funcexe.fe_evaluate = TRUE; - if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) - return FAIL; - } - else if (expr->v_type == VAR_PARTIAL) + if (expr->v_type == VAR_PARTIAL) { partial_T *partial = expr->vval.v_partial; @@ -318,6 +310,18 @@ eval_expr_typval( { return exe_typval_instr(expr, rettv); } + else if (expr->v_type == VAR_FUNC || want_func) + { + s = expr->v_type == VAR_FUNC + ? expr->vval.v_string + : tv_get_string_buf_chk_strict(expr, buf, in_vim9script()); + if (s == NULL || *s == NUL) + return FAIL; + CLEAR_FIELD(funcexe); + funcexe.fe_evaluate = TRUE; + if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) + return FAIL; + } else { s = tv_get_string_buf_chk_strict(expr, buf, in_vim9script()); @@ -346,7 +350,7 @@ eval_expr_to_bool(typval_T *expr, int *error) typval_T rettv; int res; - if (eval_expr_typval(expr, NULL, 0, NULL, &rettv) == FAIL) + if (eval_expr_typval(expr, FALSE, NULL, 0, NULL, &rettv) == FAIL) { *error = TRUE; return FALSE; diff --git a/src/evalfunc.c b/src/evalfunc.c index 0903fa8e60..ab6606f76f 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -6938,7 +6938,7 @@ indexof_eval_expr(typval_T *expr) argv[1] = *get_vim_var_tv(VV_VAL); newtv.v_type = VAR_UNKNOWN; - if (eval_expr_typval(expr, argv, 2, NULL, &newtv) == FAIL) + if (eval_expr_typval(expr, FALSE, argv, 2, NULL, &newtv) == FAIL) return FALSE; found = tv_get_bool_chk(&newtv, &error); diff --git a/src/filepath.c b/src/filepath.c index 79d4afb2e3..c30d9bf82b 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -1616,7 +1616,7 @@ checkitem_common(void *context, char_u *name, dict_T *dict) argv[0].vval.v_dict = dict; } - if (eval_expr_typval(expr, argv, 1, NULL, &rettv) == FAIL) + if (eval_expr_typval(expr, FALSE, argv, 1, NULL, &rettv) == FAIL) goto theend; // We want to use -1, but also true/false should be allowed. diff --git a/src/list.c b/src/list.c index 933480f55f..28799d5fd4 100644 --- a/src/list.c +++ b/src/list.c @@ -2333,7 +2333,7 @@ filter_map_one( copy_tv(tv, get_vim_var_tv(VV_VAL)); argv[0] = *get_vim_var_tv(VV_KEY); argv[1] = *get_vim_var_tv(VV_VAL); - if (eval_expr_typval(expr, argv, 2, fc, newtv) == FAIL) + if (eval_expr_typval(expr, FALSE, argv, 2, fc, newtv) == FAIL) goto theend; if (filtermap == FILTERMAP_FILTER) { @@ -3084,7 +3084,7 @@ list_reduce( else argv[1] = li->li_tv; - r = eval_expr_typval(expr, argv, 2, fc, rettv); + r = eval_expr_typval(expr, TRUE, argv, 2, fc, rettv); if (argv[0].v_type != VAR_NUMBER && argv[0].v_type != VAR_UNKNOWN) clear_tv(&argv[0]); @@ -3125,7 +3125,7 @@ f_reduce(typval_T *argvars, typval_T *rettv) && argvars[0].v_type != VAR_LIST && argvars[0].v_type != VAR_BLOB) { - semsg(_(e_string_list_or_blob_required), "reduce()"); + emsg(_(e_string_list_or_blob_required)); return; } diff --git a/src/proto/eval.pro b/src/proto/eval.pro index afc4d6189d..1fb36c217c 100644 --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -7,7 +7,7 @@ void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, int skip); int eval_to_bool(char_u *arg, int *error, exarg_T *eap, int skip, int use_simple_function); int eval_expr_valid_arg(typval_T *tv); funccall_T *eval_expr_get_funccal(typval_T *expr, typval_T *rettv); -int eval_expr_typval(typval_T *expr, typval_T *argv, int argc, funccall_T *fc_arg, typval_T *rettv); +int eval_expr_typval(typval_T *expr, int prefer_func, typval_T *argv, int argc, funccall_T *fc_arg, typval_T *rettv); int eval_expr_to_bool(typval_T *expr, int *error); char_u *eval_to_string_skip(char_u *arg, exarg_T *eap, int skip); void init_evalarg(evalarg_T *evalarg); diff --git a/src/strings.c b/src/strings.c index e5ad9cda3f..25c32ecaf1 100644 --- a/src/strings.c +++ b/src/strings.c @@ -1032,7 +1032,7 @@ string_reduce( break; len = (int)STRLEN(argv[1].vval.v_string); - r = eval_expr_typval(expr, argv, 2, fc, rettv); + r = eval_expr_typval(expr, TRUE, argv, 2, fc, rettv); clear_tv(&argv[0]); clear_tv(&argv[1]); diff --git a/src/testdir/test_listdict.vim b/src/testdir/test_listdict.vim index ac1f29b8fd..3ff20973a2 100644 --- a/src/testdir/test_listdict.vim +++ b/src/testdir/test_listdict.vim @@ -1037,6 +1037,10 @@ func Test_reduce() call assert_equal('Å,s,t,r,ö,m', reduce('Åström', LSTART acc, val LMIDDLE acc .. ',' .. val LEND)) call assert_equal('Å,s,t,r,ö,m', reduce('Åström', LSTART acc, val LMIDDLE acc .. ',' .. val LEND)) call assert_equal(',a,b,c', reduce('abc', LSTART acc, val LMIDDLE acc .. ',' .. val LEND, test_null_string())) + + call assert_equal(0x7d, reduce([0x30, 0x25, 0x08, 0x61], 'or')) + call assert_equal(0x7d, reduce(0z30250861, 'or')) + call assert_equal('β', reduce('ββββ', 'matchstr')) END call v9.CheckLegacyAndVim9Success(lines) @@ -1052,7 +1056,7 @@ func Test_reduce() call assert_fails("call reduce({}, { acc, val -> acc + val }, 1)", 'E1098:') call assert_fails("call reduce(0, { acc, val -> acc + val }, 1)", 'E1098:') - call assert_fails("call reduce([1, 2], 'Xdoes_not_exist')", 'E121:') + call assert_fails("call reduce([1, 2], 'Xdoes_not_exist')", 'E117:') call assert_fails("echo reduce(0z01, { acc, val -> 2 * acc + val }, '')", 'E1210:') call assert_fails("vim9 reduce(0, (acc, val) => (acc .. val), '')", 'E1252:') diff --git a/src/version.c b/src/version.c index 1809d0d2b3..de1d6e01fa 100644 --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1723, +/**/ 1722, /**/ 1721, |