]> granicus.if.org Git - vim/commitdiff
patch 8.2.1076: Vim9: no line break allowed in :if expression v8.2.1076
authorBram Moolenaar <Bram@vim.org>
Sat, 27 Jun 2020 21:07:36 +0000 (23:07 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 27 Jun 2020 21:07:36 +0000 (23:07 +0200)
Problem:    Vim9: no line break allowed in :if expression.
Solution:   Skip linebreak.

src/eval.c
src/evalvars.c
src/proto/eval.pro
src/testdir/test_vim9_cmd.vim
src/version.c

index 736023930be2cd03c98434cb2198ed7b5a0a9045..6aaa3a6ef0cab1298f61f275721884d9675c381d 100644 (file)
@@ -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;
 }
@@ -1883,6 +1890,24 @@ skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg)
     return p;
 }
 
+/*
+ * 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
@@ -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;
index 0acbd7bcf1a0b7b7ba29b6e20b804dc7cdf80873..1d6172ac7c3b07a30708d6c388f98cb2e257cd43 100644 (file)
@@ -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)
        {
index 9170385918213f8a75e6551969efdb47416be2aa..88dd8a7538dfcc9e8bea3dc5779732b992acc339 100644 (file)
@@ -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);
index 2d5bf4516ecffc278825be0d6bfd33337d289558..a818d14084563ae68c2554469cf0d951223a0392 100644 (file)
@@ -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
index c304fe5ccfe211222ee815f88050cfc219d4b770..948f561e255c79824bacc82cd01a0ebfb83d182c 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1076,
 /**/
     1075,
 /**/