aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
authorJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2019-06-22 19:40:12 -0400
committerJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2019-06-23 18:17:10 -0400
commit4653b5943f2ccdb65fa1e099853d4d680abc3f83 (patch)
tree0a353ec0ae9fab6d3f95d6143a3b5ebc10ad5aeb /src/nvim/eval.c
parent2813c83ea10b157974bdff7ceec9c3fc7f0d3380 (diff)
downloadrneovim-4653b5943f2ccdb65fa1e099853d4d680abc3f83.tar.gz
rneovim-4653b5943f2ccdb65fa1e099853d4d680abc3f83.tar.bz2
rneovim-4653b5943f2ccdb65fa1e099853d4d680abc3f83.zip
vim-patch:8.1.0747: map() with a bad expression doesn't give an error
Problem: map() with a bad expression doesn't give an error. (Ingo Karkat) Solution: Check for giving an error message. (closes vim/vim#3800) https://github.com/vim/vim/commit/ce9d50df07402cb8e196537a9c4505845adecabc
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index ce0b192545..c5caf80700 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -955,6 +955,28 @@ eval_to_bool(
return retval;
}
+// Call eval1() and give an error message if not done at a lower level.
+static int eval1_emsg(char_u **arg, typval_T *rettv, bool evaluate)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
+{
+ const int did_emsg_before = did_emsg;
+ const int called_emsg_before = called_emsg;
+
+ const int ret = eval1(arg, rettv, evaluate);
+ if (ret == FAIL) {
+ // Report the invalid expression unless the expression evaluation has
+ // been cancelled due to an aborting error, an interrupt, or an
+ // exception, or we already gave a more specific error.
+ // Also check called_emsg for when using assert_fails().
+ if (!aborting()
+ && did_emsg == did_emsg_before
+ && called_emsg == called_emsg_before) {
+ emsgf(_(e_invexpr2), arg);
+ }
+ }
+ return ret;
+}
+
static int eval_expr_typval(const typval_T *expr, typval_T *argv,
int argc, typval_T *rettv)
FUNC_ATTR_NONNULL_ARG(1, 2, 4)
@@ -987,7 +1009,7 @@ static int eval_expr_typval(const typval_T *expr, typval_T *argv,
return FAIL;
}
s = skipwhite(s);
- if (eval1(&s, rettv, true) == FAIL) {
+ if (eval1_emsg(&s, rettv, true) == FAIL) {
return FAIL;
}
if (*s != NUL) { // check for trailing chars after expr
@@ -6368,7 +6390,7 @@ call_func(
partial_T *partial, // optional, can be NULL
dict_T *selfdict_in // Dictionary for "self"
)
- FUNC_ATTR_NONNULL_ARG(5)
+ FUNC_ATTR_NONNULL_ARG(1, 3, 5, 9)
{
int ret = FAIL;
int error = ERROR_NONE;
@@ -8891,6 +8913,7 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
}
hash_unlock(ht);
} else {
+ // argvars[0].v_type == VAR_LIST
vimvars[VV_KEY].vv_type = VAR_NUMBER;
for (listitem_T *li = tv_list_first(l); li != NULL;) {
@@ -8921,6 +8944,7 @@ static void filter_map(typval_T *argvars, typval_T *rettv, int map)
}
static int filter_map_one(typval_T *tv, typval_T *expr, int map, int *remp)
+ FUNC_ATTR_NONNULL_ARG(1, 2)
{
typval_T rettv;
typval_T argv[3];
@@ -14655,7 +14679,6 @@ do_searchpair(
pos_T save_cursor;
pos_T save_pos;
int n;
- int r;
int nest = 1;
bool use_skip = false;
int options = SEARCH_KEEP;
@@ -14728,7 +14751,7 @@ do_searchpair(
save_pos = curwin->w_cursor;
curwin->w_cursor = pos;
bool err = false;
- r = eval_expr_to_bool(skip, &err);
+ const bool r = eval_expr_to_bool(skip, &err);
curwin->w_cursor = save_pos;
if (err) {
/* Evaluating {skip} caused an error, break here. */
@@ -20525,7 +20548,6 @@ void ex_execute(exarg_T *eap)
char_u *arg = eap->arg;
typval_T rettv;
int ret = OK;
- char_u *p;
garray_T ga;
int save_did_emsg = did_emsg;
@@ -20534,17 +20556,8 @@ void ex_execute(exarg_T *eap)
if (eap->skip)
++emsg_skip;
while (*arg != NUL && *arg != '|' && *arg != '\n') {
- p = arg;
- if (eval1(&arg, &rettv, !eap->skip) == FAIL) {
- /*
- * Report the invalid expression unless the expression evaluation
- * has been cancelled due to an aborting error, an interrupt, or an
- * exception.
- */
- if (!aborting() && did_emsg == save_did_emsg) {
- EMSG2(_(e_invexpr2), p);
- }
- ret = FAIL;
+ ret = eval1_emsg(&arg, &rettv, !eap->skip);
+ if (ret == FAIL) {
break;
}