To: vim_dev@googlegroups.com Subject: Patch 8.2.1076 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1076 Problem: Vim9: no line break allowed in :if expression. Solution: Skip linebreak. Files: src/eval.c, src/proto/eval.pro, src/evalvars.c, src/testdir/test_vim9_cmd.vim *** ../vim-8.2.1075/src/eval.c 2020-06-27 21:56:13.764343724 +0200 --- src/eval.c 2020-06-27 22:55:44.094945696 +0200 *************** *** 166,175 **** { typval_T tv; varnumber_T retval = FALSE; if (skip) ++emsg_skip; ! if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE) == FAIL) *error = TRUE; else { --- 166,181 ---- { 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, &evalarg) == FAIL) *error = TRUE; else { *************** *** 182,187 **** --- 188,194 ---- } if (skip) --emsg_skip; + clear_evalarg(&evalarg, eap); return (int)retval; } *************** *** 1884,1889 **** --- 1891,1914 ---- } /* + * 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,1949 **** 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; ! } return ret; } --- 1959,1965 ---- if (eap != NULL) eap->nextcmd = check_nextcmd(p); ! clear_evalarg(evalarg, eap); return ret; } *************** *** 5223,5228 **** --- 5239,5245 ---- arg = skipwhite(arg); } eap->nextcmd = check_nextcmd(arg); + clear_evalarg(&evalarg, eap); if (eap->skip) --emsg_skip; *** ../vim-8.2.1075/src/proto/eval.pro 2020-06-27 21:17:55.359214424 +0200 --- src/proto/eval.pro 2020-06-27 22:45:49.897705439 +0200 *************** *** 30,35 **** --- 30,36 ---- 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); *** ../vim-8.2.1075/src/evalvars.c 2020-06-27 18:06:42.148575132 +0200 --- src/evalvars.c 2020-06-27 22:45:28.101806140 +0200 *************** *** 804,810 **** i = eval0(expr, &rettv, eap, &evalarg); if (eap->skip) --emsg_skip; ! vim_free(evalarg.eval_tofree); } if (eap->skip) { --- 804,810 ---- i = eval0(expr, &rettv, eap, &evalarg); if (eap->skip) --emsg_skip; ! clear_evalarg(&evalarg, eap); } if (eap->skip) { *** ../vim-8.2.1075/src/testdir/test_vim9_cmd.vim 2020-06-27 21:56:13.764343724 +0200 --- src/testdir/test_vim9_cmd.vim 2020-06-27 22:49:19.132736358 +0200 *************** *** 101,105 **** --- 101,146 ---- 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 *** ../vim-8.2.1075/src/version.c 2020-06-27 21:56:13.764343724 +0200 --- src/version.c 2020-06-27 22:32:57.921215615 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1076, /**/ -- ARTHUR: CHARGE! [The mighty ARMY charges. Thundering noise of feet. Clatter of coconuts. Shouts etc. Suddenly there is a wail of a siren and a couple of police cars roar round in front of the charging ARMY and the POLICE leap out and stop them. TWO POLICEMAN and the HISTORIAN'S WIFE. Black Marias skid up behind them.] HISTORIAN'S WIFE: They're the ones, I'm sure. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///