To: vim_dev@googlegroups.com Subject: Patch 9.0.1505 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1505 Problem: Error when heredoc content looks like heredoc. Solution: Handle curly expressions. (closes #12325) Files: src/eval.c, src/userfunc.c, src/vim.h, src/testdir/test_let.vim, src/testdir/test_vim9_assign.vim *** ../vim-9.0.1504/src/eval.c 2023-04-13 22:12:46.300718943 +0100 --- src/eval.c 2023-05-02 16:19:44.051000651 +0100 *************** *** 6581,6587 **** int br_nest = 0; char_u *p; int len; ! int vim9script = in_vim9script(); if (expr_start != NULL) { --- 6581,6587 ---- int br_nest = 0; char_u *p; int len; ! int allow_curly = (flags & FNE_ALLOW_CURLY) || !in_vim9script(); if (expr_start != NULL) { *************** *** 6591,6602 **** // Quick check for valid starting character. if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) ! && (*arg != '{' || vim9script)) return arg; for (p = arg; *p != NUL && (eval_isnamec(*p) ! || (*p == '{' && !vim9script) || ((flags & FNE_INCL_BR) && (*p == '[' || (*p == '.' && eval_isdictc(p[1])))) || mb_nest != 0 --- 6591,6602 ---- // Quick check for valid starting character. if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) ! && (*arg != '{' || !allow_curly)) return arg; for (p = arg; *p != NUL && (eval_isnamec(*p) ! || (*p == '{' && allow_curly) || ((flags & FNE_INCL_BR) && (*p == '[' || (*p == '.' && eval_isdictc(p[1])))) || mb_nest != 0 *************** *** 6637,6643 **** --br_nest; } ! if (br_nest == 0 && !vim9script) { if (*p == '{') { --- 6637,6643 ---- --br_nest; } ! if (br_nest == 0 && allow_curly) { if (*p == '{') { *** ../vim-9.0.1504/src/userfunc.c 2023-04-19 14:21:19.078048657 +0100 --- src/userfunc.c 2023-05-02 16:18:35.495061306 +0100 *************** *** 1143,1149 **** skip_until = vim_strnsave(p, skiptowhite(p) - p); getline_options = GETLINE_NONE; is_heredoc = TRUE; ! if (eap->cmdidx == CMD_def && nesting == 0) heredoc_concat_len = newlines->ga_len + 1; } --- 1143,1149 ---- skip_until = vim_strnsave(p, skiptowhite(p) - p); getline_options = GETLINE_NONE; is_heredoc = TRUE; ! if (vim9_function && nesting == 0) heredoc_concat_len = newlines->ga_len + 1; } *************** *** 1153,1175 **** // and ":cmd [a, b] =<< [trim] EOF" // and "lines =<< [trim] EOF" for Vim9 // Where "cmd" can be "let", "var", "final" or "const". ! arg = skipwhite(skiptowhite(p)); ! if (*arg == '[') ! arg = vim_strchr(arg, ']'); ! if (arg != NULL) { ! int found = (eap->cmdidx == CMD_def && arg[0] == '=' ! && arg[1] == '<' && arg[2] =='<'); ! ! if (!found) ! // skip over the argument after "cmd" ! arg = skipwhite(skiptowhite(arg)); ! if (found || (arg[0] == '=' && arg[1] == '<' ! && arg[2] =='<' ! && (checkforcmd(&p, "let", 2) ! || checkforcmd(&p, "var", 3) ! || checkforcmd(&p, "final", 5) ! || checkforcmd(&p, "const", 5)))) { p = skipwhite(arg + 3); while (TRUE) --- 1153,1172 ---- // and ":cmd [a, b] =<< [trim] EOF" // and "lines =<< [trim] EOF" for Vim9 // Where "cmd" can be "let", "var", "final" or "const". ! arg = p; ! if (checkforcmd(&arg, "let", 2) ! || checkforcmd(&arg, "var", 3) ! || checkforcmd(&arg, "final", 5) ! || checkforcmd(&arg, "const", 5) ! || vim9_function) { ! while (vim_strchr((char_u *)"$@&", *arg) != NULL) ! ++arg; ! arg = skipwhite(find_name_end(arg, NULL, NULL, ! FNE_INCL_BR | FNE_ALLOW_CURLY)); ! if (vim9_function && *arg == ':') ! arg = skipwhite(skip_type(skipwhite(arg + 1), FALSE)); ! if (arg[0] == '=' && arg[1] == '<' && arg[2] =='<') { p = skipwhite(arg + 3); while (TRUE) *** ../vim-9.0.1504/src/vim.h 2023-04-13 19:15:50.023391985 +0100 --- src/vim.h 2023-05-02 16:18:35.495061306 +0100 *************** *** 2758,2763 **** --- 2758,2764 ---- // flags for find_name_end() #define FNE_INCL_BR 1 // include [] in name #define FNE_CHECK_START 2 // check name starts with valid character + #define FNE_ALLOW_CURLY 4 // always allow curly braces name // BSD is supposed to cover FreeBSD and similar systems. #if (defined(SUN_SYSTEM) || defined(BSD) || defined(__FreeBSD_kernel__)) \ *** ../vim-9.0.1504/src/testdir/test_let.vim 2022-11-05 20:21:50.601151478 +0000 --- src/testdir/test_let.vim 2023-05-02 16:18:35.491061310 +0100 *************** *** 337,343 **** call assert_report('No exception thrown') catch /E488:/ catch ! call assert_report("Caught exception: " .. v:exception) endtry let text =<< trim END --- 337,379 ---- call assert_report('No exception thrown') catch /E488:/ catch ! call assert_report('Caught exception: ' .. v:exception) ! endtry ! ! try ! let &commentstring =<< trim TEXT ! change ! insert ! append ! TEXT ! call assert_report('No exception thrown') ! catch /E730:/ ! catch ! call assert_report('Caught exception: ' .. v:exception) ! endtry ! ! try ! let $SOME_ENV_VAR =<< trim TEXT ! change ! insert ! append ! TEXT ! call assert_report('No exception thrown') ! catch /E730:/ ! catch ! call assert_report('Caught exception: ' .. v:exception) ! endtry ! ! try ! let @r =<< trim TEXT ! change ! insert ! append ! TEXT ! call assert_report('No exception thrown') ! catch /E730:/ ! catch ! call assert_report('Caught exception: ' .. v:exception) endtry let text =<< trim END *************** *** 506,511 **** --- 542,573 ---- z END call assert_equal([' x', ' \y', ' z'], [a, b, c]) + + " unpack assignment without whitespace + let[a,b,c]=< =<< trim TEXT + var foo =<< trim FOO + TEXT + assert_equal(['var foo =<< trim FOO'], text) + END + v9.CheckDefAndScriptSuccess(lines) + + # extra whitespace before type is allowed + lines =<< trim END + var text: list =<< trim TEXT + var foo =<< trim FOO + TEXT + assert_equal(['var foo =<< trim FOO'], text) + END + v9.CheckDefAndScriptSuccess(lines) + + # missing whitespace before type is an error + lines =<< trim END + var text:list =<< trim TEXT + var foo =<< trim FOO + TEXT + assert_equal(['var foo =<< trim FOO'], text) + END + v9.CheckDefAndScriptFailure(lines, 'E1069:') + + # assign heredoc to list slice + lines =<< trim END + var text = [''] + text[ : ] =<< trim TEXT + var foo =<< trim FOO + TEXT + assert_equal(['var foo =<< trim FOO'], text) + END + v9.CheckDefAndScriptSuccess(lines) + + # assign heredoc to curly braces name in legacy function in Vim9 script + lines =<< trim END + vim9script + func Func() + let foo_3_bar = [''] + let foo_{1 + 2}_bar[ : ] =<< trim TEXT + var foo =<< trim FOO + TEXT + call assert_equal(['var foo =<< trim FOO'], foo_3_bar) + endfunc + Func() + END + v9.CheckScriptSuccess(lines) + v9.CheckDefFailure(['var lines =<< trim END X', 'END'], 'E488:') v9.CheckDefFailure(['var lines =<< trim END " comment', 'END'], 'E488:') *** ../vim-9.0.1504/src/version.c 2023-05-01 22:36:52.870894672 +0100 --- src/version.c 2023-05-02 16:20:42.170957010 +0100 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1505, /**/ -- Are leaders born or made? And if they're made, can we return them under warranty? (Scott Adams - The Dilbert principle) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///