summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-06-27 23:07:36 +0200
committerBram Moolenaar <Bram@vim.org>2020-06-27 23:07:36 +0200
commitfaf8626b79e380fe81e7ae2439a535ed7619d27b (patch)
tree6814686cce2bf81a6ccc2c78ef1894cd22d2ba75
parent7e8967fdcdf45caf08753bb791dc3779e78b34c8 (diff)
patch 8.2.1076: Vim9: no line break allowed in :if expressionv8.2.1076
Problem: Vim9: no line break allowed in :if expression. Solution: Skip linebreak.
-rw-r--r--src/eval.c39
-rw-r--r--src/evalvars.c2
-rw-r--r--src/proto/eval.pro1
-rw-r--r--src/testdir/test_vim9_cmd.vim41
-rw-r--r--src/version.c2
5 files changed, 73 insertions, 12 deletions
diff --git a/src/eval.c b/src/eval.c
index 736023930b..6aaa3a6ef0 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -166,10 +166,16 @@ eval_to_bool(
{
typval_T tv;
varnumber_T retval = FALSE;
+ evalarg_T evalarg;
+
+ CLEAR_FIELD(evalarg);
+ evalarg.eval_flags = skip ? 0 : EVAL_EVALUATE;
+ evalarg.eval_cookie = eap != NULL && eap->getline == getsourceline
+ ? eap->cookie : NULL;
if (skip)
++emsg_skip;
- if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE) == FAIL)
+ if (eval0(arg, &tv, eap, &evalarg) == FAIL)
*error = TRUE;
else
{
@@ -182,6 +188,7 @@ eval_to_bool(
}
if (skip)
--emsg_skip;
+ clear_evalarg(&evalarg, eap);
return (int)retval;
}
@@ -1884,6 +1891,24 @@ skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg)
}
/*
+ * After using "evalarg" filled from "eap" free the memory.
+ */
+ void
+clear_evalarg(evalarg_T *evalarg, exarg_T *eap)
+{
+ if (evalarg != NULL && eap != NULL && evalarg->eval_tofree != NULL)
+ {
+ // We may need to keep the original command line, e.g. for
+ // ":let" it has the variable names. But we may also need the
+ // new one, "nextcmd" points into it. Keep both.
+ vim_free(eap->cmdline_tofree);
+ eap->cmdline_tofree = *eap->cmdlinep;
+ *eap->cmdlinep = evalarg->eval_tofree;
+ evalarg->eval_tofree = NULL;
+ }
+}
+
+/*
* The "evaluate" argument: When FALSE, the argument is only parsed but not
* executed. The function may return OK, but the rettv will be of type
* VAR_UNKNOWN. The function still returns FAIL for a syntax error.
@@ -1934,16 +1959,7 @@ eval0(
if (eap != NULL)
eap->nextcmd = check_nextcmd(p);
- if (evalarg != NULL && eap != NULL && evalarg->eval_tofree != NULL)
- {
- // We may need to keep the original command line, e.g. for
- // ":let" it has the variable names. But we may also need the
- // new one, "nextcmd" points into it. Keep both.
- vim_free(eap->cmdline_tofree);
- eap->cmdline_tofree = *eap->cmdlinep;
- *eap->cmdlinep = evalarg->eval_tofree;
- evalarg->eval_tofree = NULL;
- }
+ clear_evalarg(evalarg, eap);
return ret;
}
@@ -5223,6 +5239,7 @@ ex_echo(exarg_T *eap)
arg = skipwhite(arg);
}
eap->nextcmd = check_nextcmd(arg);
+ clear_evalarg(&evalarg, eap);
if (eap->skip)
--emsg_skip;
diff --git a/src/evalvars.c b/src/evalvars.c
index 0acbd7bcf1..1d6172ac7c 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -804,7 +804,7 @@ ex_let(exarg_T *eap)
i = eval0(expr, &rettv, eap, &evalarg);
if (eap->skip)
--emsg_skip;
- vim_free(evalarg.eval_tofree);
+ clear_evalarg(&evalarg, eap);
}
if (eap->skip)
{
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index 9170385918..88dd8a7538 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -30,6 +30,7 @@ int pattern_match(char_u *pat, char_u *text, int ic);
char_u *eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext);
char_u *eval_next_line(evalarg_T *evalarg);
char_u *skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg);
+void clear_evalarg(evalarg_T *evalarg, exarg_T *eap);
int eval0(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg);
int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
void eval_addblob(typval_T *tv1, typval_T *tv2);
diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim
index 2d5bf4516e..a818d14084 100644
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -101,5 +101,46 @@ def Test_echo_linebreak()
CheckScriptSuccess(lines)
enddef
+def Test_if_linebreak()
+ let lines =<< trim END
+ vim9script
+ if 1 &&
+ 2
+ || 3
+ g:res = 42
+ endif
+ assert_equal(42, g:res)
+ END
+ CheckScriptSuccess(lines)
+ unlet g:res
+
+ lines =<< trim END
+ vim9script
+ if 1 &&
+ 0
+ g:res = 0
+ elseif 0 ||
+ 0
+ || 1
+ g:res = 12
+ endif
+ assert_equal(12, g:res)
+ END
+ CheckScriptSuccess(lines)
+ unlet g:res
+enddef
+
+def Test_while_linebreak()
+ " TODO: line break in :while expression doesn't work yet
+ let lines =<< trim END
+ vim9script
+ let nr = 0
+ while nr < 10 + 3
+ nr = nr + 4
+ endwhile
+ assert_equal(16, nr)
+ END
+ CheckScriptSuccess(lines)
+enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/version.c b/src/version.c
index c304fe5ccf..948f561e25 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1076,
+/**/
1075,
/**/
1074,