]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1723: Fix regression in {func} argument of reduce() v9.0.1723
authorzeertzjq <zeertzjq@outlook.com>
Thu, 17 Aug 2023 20:15:47 +0000 (22:15 +0200)
committerChristian Brabandt <cb@256bit.org>
Thu, 17 Aug 2023 20:15:47 +0000 (22:15 +0200)
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>
src/blob.c
src/eval.c
src/evalfunc.c
src/filepath.c
src/list.c
src/proto/eval.pro
src/strings.c
src/testdir/test_listdict.vim
src/version.c

index 9b409f614e78958a4d194d994e90f3ced2b5f229..c5d7eaed64721ffa405153d6af6e23f773fe5c1f 100644 (file)
@@ -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)
index 8660a25d508aa109c2b4072223d6bd01e6891a70..cfcec9bac0b8caf6d14b4524894a4c026586d3d0 100644 (file)
@@ -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;
index 0903fa8e60b8e91b2b0de80bfc67ea518043f836..ab6606f76fd9374f4c6f70679c020fcf171e71e9 100644 (file)
@@ -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);
index 79d4afb2e3c7803a2081bcda0236aad2b6c34342..c30d9bf82bd301623de54934ceaf7507630d65ba 100644 (file)
@@ -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.
index 933480f55f510249c0c8710fc5ab9448696ff0d5..28799d5fd4752a842dad7c45f4feae65e2854ed3 100644 (file)
@@ -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;
     }
 
index afc4d6189df7c29c4e77fb2c0808c00d0a5ff09d..1fb36c217cfb424ea2116896fa92056b2c153f1c 100644 (file)
@@ -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);
index e5ad9cda3f143ff151a1f43db273e4e63f833398..25c32ecaf1954f66a1eaed6c8c490db9e24605b6 100644 (file)
@@ -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]);
index ac1f29b8fde9dcde411230dd2401a8574411cf27..3ff20973a23c7353c7a9e7067a869af26cc8ac4d 100644 (file)
@@ -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:')
index 1809d0d2b3728ee7155b3885b95997bf0ebef0d7..de1d6e01facb3bab1cd8f8b41d161e2e7d050f61 100644 (file)
@@ -695,6 +695,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1723,
 /**/
     1722,
 /**/