mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 19:38:20 +00:00
Merge pull request #24766 from zeertzjq/vim-9.0.1722
vim-patch:9.0.{1722,1723}
This commit is contained in:
@@ -820,21 +820,19 @@ 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));
|
&& (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)
|
/// Evaluate an expression, which can be a function, partial or string.
|
||||||
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
|
/// 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;
|
funcexe_T funcexe = FUNCEXE_INIT;
|
||||||
|
|
||||||
if (expr->v_type == VAR_FUNC) {
|
if (expr->v_type == VAR_PARTIAL) {
|
||||||
const char *const s = expr->vval.v_string;
|
|
||||||
if (s == NULL || *s == NUL) {
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
funcexe.fe_evaluate = true;
|
|
||||||
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;
|
partial_T *const partial = expr->vval.v_partial;
|
||||||
if (partial == NULL) {
|
if (partial == NULL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -848,8 +846,18 @@ int eval_expr_typval(const typval_T *expr, typval_T *argv, int argc, typval_T *r
|
|||||||
if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) {
|
if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
} 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;
|
||||||
|
if (call_func(s, -1, rettv, argc, argv, &funcexe) == FAIL) {
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
char buf[NUMBUFLEN];
|
|
||||||
char *s = (char *)tv_get_string_buf_chk(expr, buf);
|
char *s = (char *)tv_get_string_buf_chk(expr, buf);
|
||||||
if (s == NULL) {
|
if (s == NULL) {
|
||||||
return FAIL;
|
return FAIL;
|
||||||
@@ -874,7 +882,7 @@ bool eval_expr_to_bool(const typval_T *expr, bool *error)
|
|||||||
{
|
{
|
||||||
typval_T argv, rettv;
|
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;
|
*error = true;
|
||||||
return false;
|
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);
|
tv_copy(tv, &vimvars[VV_VAL].vv_tv);
|
||||||
argv[0] = vimvars[VV_KEY].vv_tv;
|
argv[0] = vimvars[VV_KEY].vv_tv;
|
||||||
argv[1] = vimvars[VV_VAL].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;
|
goto theend;
|
||||||
}
|
}
|
||||||
if (filtermap == FILTERMAP_FILTER) {
|
if (filtermap == FILTERMAP_FILTER) {
|
||||||
|
@@ -147,6 +147,8 @@ PRAGMA_DIAG_POP
|
|||||||
|
|
||||||
static const char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob");
|
static const char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob");
|
||||||
static const char *e_invalwindow = N_("E957: Invalid window number");
|
static const char *e_invalwindow = N_("E957: Invalid window number");
|
||||||
|
static const char e_argument_of_str_must_be_list_string_or_dictionary[]
|
||||||
|
= N_("E706: Argument of %s must be a List, String or Dictionary");
|
||||||
static const char e_invalid_submatch_number_nr[]
|
static const char e_invalid_submatch_number_nr[]
|
||||||
= N_("E935: Invalid submatch number: %d");
|
= N_("E935: Invalid submatch number: %d");
|
||||||
static const char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial value");
|
static const char *e_reduceempty = N_("E998: Reduce of an empty %s with no initial value");
|
||||||
@@ -997,8 +999,8 @@ static void f_count(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
n = count_dict(argvars[0].vval.v_dict, &argvars[1], ic);
|
n = count_dict(argvars[0].vval.v_dict, &argvars[1], ic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!error) {
|
||||||
semsg(_(e_listdictarg), "count()");
|
semsg(_(e_argument_of_str_must_be_list_string_or_dictionary), "count()");
|
||||||
}
|
}
|
||||||
rettv->vval.v_number = n;
|
rettv->vval.v_number = n;
|
||||||
}
|
}
|
||||||
@@ -2951,7 +2953,7 @@ static void f_wait(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
const int called_emsg_before = called_emsg;
|
const int called_emsg_before = called_emsg;
|
||||||
|
|
||||||
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, timeout,
|
LOOP_PROCESS_EVENTS_UNTIL(&main_loop, main_loop.events, timeout,
|
||||||
eval_expr_typval(&expr, &argv, 0, &exprval) != OK
|
eval_expr_typval(&expr, false, &argv, 0, &exprval) != OK
|
||||||
|| tv_get_number_chk(&exprval, &error)
|
|| tv_get_number_chk(&exprval, &error)
|
||||||
|| called_emsg > called_emsg_before || error || got_int);
|
|| called_emsg > called_emsg_before || error || got_int);
|
||||||
|
|
||||||
@@ -3513,7 +3515,7 @@ static varnumber_T indexof_eval_expr(typval_T *expr)
|
|||||||
typval_T newtv;
|
typval_T newtv;
|
||||||
newtv.v_type = VAR_UNKNOWN;
|
newtv.v_type = VAR_UNKNOWN;
|
||||||
|
|
||||||
if (eval_expr_typval(expr, argv, 2, &newtv) == FAIL) {
|
if (eval_expr_typval(expr, false, argv, 2, &newtv) == FAIL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5535,7 +5537,7 @@ static varnumber_T readdir_checkitem(void *context, const char *name)
|
|||||||
argv[0].vval.v_string = (char *)name;
|
argv[0].vval.v_string = (char *)name;
|
||||||
|
|
||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
if (eval_expr_typval(expr, argv, 1, &rettv) == FAIL) {
|
if (eval_expr_typval(expr, false, argv, 1, &rettv) == FAIL) {
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6257,7 +6259,7 @@ static void reduce_list(typval_T *argvars, typval_T *expr, typval_T *rettv)
|
|||||||
argv[1] = *TV_LIST_ITEM_TV(li);
|
argv[1] = *TV_LIST_ITEM_TV(li);
|
||||||
rettv->v_type = VAR_UNKNOWN;
|
rettv->v_type = VAR_UNKNOWN;
|
||||||
|
|
||||||
const int r = eval_expr_typval(expr, argv, 2, rettv);
|
const int r = eval_expr_typval(expr, true, argv, 2, rettv);
|
||||||
|
|
||||||
tv_clear(&argv[0]);
|
tv_clear(&argv[0]);
|
||||||
if (r == FAIL || called_emsg != called_emsg_start) {
|
if (r == FAIL || called_emsg != called_emsg_start) {
|
||||||
@@ -6304,7 +6306,7 @@ static void reduce_string(typval_T *argvars, typval_T *expr, typval_T *rettv)
|
|||||||
.vval.v_string = xstrnsave(p, (size_t)len),
|
.vval.v_string = xstrnsave(p, (size_t)len),
|
||||||
};
|
};
|
||||||
|
|
||||||
const int r = eval_expr_typval(expr, argv, 2, rettv);
|
const int r = eval_expr_typval(expr, true, argv, 2, rettv);
|
||||||
|
|
||||||
tv_clear(&argv[0]);
|
tv_clear(&argv[0]);
|
||||||
tv_clear(&argv[1]);
|
tv_clear(&argv[1]);
|
||||||
@@ -6352,7 +6354,7 @@ static void reduce_blob(typval_T *argvars, typval_T *expr, typval_T *rettv)
|
|||||||
.vval.v_number = tv_blob_get(b, i),
|
.vval.v_number = tv_blob_get(b, i),
|
||||||
};
|
};
|
||||||
|
|
||||||
const int r = eval_expr_typval(expr, argv, 2, rettv);
|
const int r = eval_expr_typval(expr, true, argv, 2, rettv);
|
||||||
|
|
||||||
if (r == FAIL || called_emsg != called_emsg_start) {
|
if (r == FAIL || called_emsg != called_emsg_start) {
|
||||||
return;
|
return;
|
||||||
|
@@ -1627,7 +1627,8 @@ func Test_count()
|
|||||||
call assert_equal(2, count("fooooo", "oo"))
|
call assert_equal(2, count("fooooo", "oo"))
|
||||||
call assert_equal(0, count("foo", ""))
|
call assert_equal(0, count("foo", ""))
|
||||||
|
|
||||||
call assert_fails('call count(0, 0)', 'E712:')
|
call assert_fails('call count(0, 0)', 'E706:')
|
||||||
|
call assert_fails('call count("", "", {})', ['E728:', 'E728:'])
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_changenr()
|
func Test_changenr()
|
||||||
|
@@ -944,6 +944,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('Å,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, v:_null_string))
|
call assert_equal(',a,b,c', reduce('abc', LSTART acc, val LMIDDLE acc .. ',' .. val LEND, v:_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
|
END
|
||||||
call CheckLegacyAndVim9Success(lines)
|
call CheckLegacyAndVim9Success(lines)
|
||||||
|
|
||||||
@@ -958,7 +962,7 @@ func Test_reduce()
|
|||||||
|
|
||||||
call assert_fails("call reduce({}, { acc, val -> acc + val }, 1)", 'E1098:')
|
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(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("echo reduce(0z01, { acc, val -> 2 * acc + val }, '')", 'E1210:')
|
||||||
|
|
||||||
" call assert_fails("vim9 reduce(0, (acc, val) => (acc .. val), '')", 'E1252:')
|
" call assert_fails("vim9 reduce(0, (acc, val) => (acc .. val), '')", 'E1252:')
|
||||||
|
Reference in New Issue
Block a user