Patch 8.2.2668
Problem:    Vim9: omitting "call" for "confirm()" does not give an error.
Solution:   Do not recognize a modifier followed by "(".
Files:      src/ex_docmd.c, src/testdir/test_vim9_builtin.vim


*** ../vim-8.2.2667/src/ex_docmd.c      2021-03-25 22:15:24.404073755 +0100
--- src/ex_docmd.c      2021-03-27 22:15:22.836193546 +0100
***************
*** 2685,2690 ****
--- 2685,2742 ----
  }
  
  /*
+  * Check for an Ex command with optional tail.
+  * If there is a match advance "pp" to the argument and return TRUE.
+  * If "noparen" is TRUE do not recognize the command followed by "(".
+  */
+     static int
+ checkforcmd_opt(
+     char_u    **pp,           // start of command
+     char      *cmd,           // name of command
+     int               len,            // required length
+     int               noparen)
+ {
+     int               i;
+ 
+     for (i = 0; cmd[i] != NUL; ++i)
+       if (((char_u *)cmd)[i] != (*pp)[i])
+           break;
+     if (i >= len && !isalpha((*pp)[i])
+                          && (*pp)[i] != '_' && (!noparen || (*pp)[i] != '('))
+     {
+       *pp = skipwhite(*pp + i);
+       return TRUE;
+     }
+     return FALSE;
+ }
+ 
+ /*
+  * Check for an Ex command with optional tail.
+  * If there is a match advance "pp" to the argument and return TRUE.
+  */
+     int
+ checkforcmd(
+     char_u    **pp,           // start of command
+     char      *cmd,           // name of command
+     int               len)            // required length
+ {
+     return checkforcmd_opt(pp, cmd, len, FALSE);
+ }
+ 
+ /*
+  * Check for an Ex command with optional tail, not followed by "(".
+  * If there is a match advance "pp" to the argument and return TRUE.
+  */
+     static int
+ checkforcmd_noparen(
+     char_u    **pp,           // start of command
+     char      *cmd,           // name of command
+     int               len)            // required length
+ {
+     return checkforcmd_opt(pp, cmd, len, TRUE);
+ }
+ 
+ /*
   * Parse and skip over command modifiers:
   * - update eap->cmd
   * - store flags in "cmod".
***************
*** 2770,2820 ****
        switch (*p)
        {
            // When adding an entry, also modify cmd_exists().
!           case 'a':   if (!checkforcmd(&eap->cmd, "aboveleft", 3))
                            break;
                        cmod->cmod_split |= WSP_ABOVE;
                        continue;
  
!           case 'b':   if (checkforcmd(&eap->cmd, "belowright", 3))
                        {
                            cmod->cmod_split |= WSP_BELOW;
                            continue;
                        }
!                       if (checkforcmd(&eap->cmd, "browse", 3))
                        {
  #ifdef FEAT_BROWSE_CMD
                            cmod->cmod_flags |= CMOD_BROWSE;
  #endif
                            continue;
                        }
!                       if (!checkforcmd(&eap->cmd, "botright", 2))
                            break;
                        cmod->cmod_split |= WSP_BOT;
                        continue;
  
!           case 'c':   if (!checkforcmd(&eap->cmd, "confirm", 4))
                            break;
  #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
                        cmod->cmod_flags |= CMOD_CONFIRM;
  #endif
                        continue;
  
!           case 'k':   if (checkforcmd(&eap->cmd, "keepmarks", 3))
                        {
                            cmod->cmod_flags |= CMOD_KEEPMARKS;
                            continue;
                        }
!                       if (checkforcmd(&eap->cmd, "keepalt", 5))
                        {
                            cmod->cmod_flags |= CMOD_KEEPALT;
                            continue;
                        }
!                       if (checkforcmd(&eap->cmd, "keeppatterns", 5))
                        {
                            cmod->cmod_flags |= CMOD_KEEPPATTERNS;
                            continue;
                        }
!                       if (!checkforcmd(&eap->cmd, "keepjumps", 5))
                            break;
                        cmod->cmod_flags |= CMOD_KEEPJUMPS;
                        continue;
--- 2822,2872 ----
        switch (*p)
        {
            // When adding an entry, also modify cmd_exists().
!           case 'a':   if (!checkforcmd_noparen(&eap->cmd, "aboveleft", 3))
                            break;
                        cmod->cmod_split |= WSP_ABOVE;
                        continue;
  
!           case 'b':   if (checkforcmd_noparen(&eap->cmd, "belowright", 3))
                        {
                            cmod->cmod_split |= WSP_BELOW;
                            continue;
                        }
!                       if (checkforcmd_opt(&eap->cmd, "browse", 3, TRUE))
                        {
  #ifdef FEAT_BROWSE_CMD
                            cmod->cmod_flags |= CMOD_BROWSE;
  #endif
                            continue;
                        }
!                       if (!checkforcmd_noparen(&eap->cmd, "botright", 2))
                            break;
                        cmod->cmod_split |= WSP_BOT;
                        continue;
  
!           case 'c':   if (!checkforcmd_opt(&eap->cmd, "confirm", 4, TRUE))
                            break;
  #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
                        cmod->cmod_flags |= CMOD_CONFIRM;
  #endif
                        continue;
  
!           case 'k':   if (checkforcmd_noparen(&eap->cmd, "keepmarks", 3))
                        {
                            cmod->cmod_flags |= CMOD_KEEPMARKS;
                            continue;
                        }
!                       if (checkforcmd_noparen(&eap->cmd, "keepalt", 5))
                        {
                            cmod->cmod_flags |= CMOD_KEEPALT;
                            continue;
                        }
!                       if (checkforcmd_noparen(&eap->cmd, "keeppatterns", 5))
                        {
                            cmod->cmod_flags |= CMOD_KEEPPATTERNS;
                            continue;
                        }
!                       if (!checkforcmd_noparen(&eap->cmd, "keepjumps", 5))
                            break;
                        cmod->cmod_flags |= CMOD_KEEPJUMPS;
                        continue;
***************
*** 2823,2829 ****
                        {
                            char_u *reg_pat;
  
!                           if (!checkforcmd(&p, "filter", 4)
                                                || *p == NUL || ends_excmd(*p))
                                break;
                            if (*p == '!')
--- 2875,2881 ----
                        {
                            char_u *reg_pat;
  
!                           if (!checkforcmd_noparen(&p, "filter", 4)
                                                || *p == NUL || ends_excmd(*p))
                                break;
                            if (*p == '!')
***************
*** 2857,2901 ****
                        }
  
                        // ":hide" and ":hide | cmd" are not modifiers
!           case 'h':   if (p != eap->cmd || !checkforcmd(&p, "hide", 3)
                                               || *p == NUL || ends_excmd(*p))
                            break;
                        eap->cmd = p;
                        cmod->cmod_flags |= CMOD_HIDE;
                        continue;
  
!           case 'l':   if (checkforcmd(&eap->cmd, "lockmarks", 3))
                        {
                            cmod->cmod_flags |= CMOD_LOCKMARKS;
                            continue;
                        }
  
!                       if (!checkforcmd(&eap->cmd, "leftabove", 5))
                            break;
                        cmod->cmod_split |= WSP_ABOVE;
                        continue;
  
!           case 'n':   if (checkforcmd(&eap->cmd, "noautocmd", 3))
                        {
                            cmod->cmod_flags |= CMOD_NOAUTOCMD;
                            continue;
                        }
!                       if (!checkforcmd(&eap->cmd, "noswapfile", 3))
                            break;
                        cmod->cmod_flags |= CMOD_NOSWAPFILE;
                        continue;
  
!           case 'r':   if (!checkforcmd(&eap->cmd, "rightbelow", 6))
                            break;
                        cmod->cmod_split |= WSP_BELOW;
                        continue;
  
!           case 's':   if (checkforcmd(&eap->cmd, "sandbox", 3))
                        {
                            cmod->cmod_flags |= CMOD_SANDBOX;
                            continue;
                        }
!                       if (!checkforcmd(&eap->cmd, "silent", 3))
                            break;
                        cmod->cmod_flags |= CMOD_SILENT;
                        if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1]))
--- 2909,2953 ----
                        }
  
                        // ":hide" and ":hide | cmd" are not modifiers
!           case 'h':   if (p != eap->cmd || !checkforcmd_noparen(&p, "hide", 3)
                                               || *p == NUL || ends_excmd(*p))
                            break;
                        eap->cmd = p;
                        cmod->cmod_flags |= CMOD_HIDE;
                        continue;
  
!           case 'l':   if (checkforcmd_noparen(&eap->cmd, "lockmarks", 3))
                        {
                            cmod->cmod_flags |= CMOD_LOCKMARKS;
                            continue;
                        }
  
!                       if (!checkforcmd_noparen(&eap->cmd, "leftabove", 5))
                            break;
                        cmod->cmod_split |= WSP_ABOVE;
                        continue;
  
!           case 'n':   if (checkforcmd_noparen(&eap->cmd, "noautocmd", 3))
                        {
                            cmod->cmod_flags |= CMOD_NOAUTOCMD;
                            continue;
                        }
!                       if (!checkforcmd_noparen(&eap->cmd, "noswapfile", 3))
                            break;
                        cmod->cmod_flags |= CMOD_NOSWAPFILE;
                        continue;
  
!           case 'r':   if (!checkforcmd_noparen(&eap->cmd, "rightbelow", 6))
                            break;
                        cmod->cmod_split |= WSP_BELOW;
                        continue;
  
!           case 's':   if (checkforcmd_noparen(&eap->cmd, "sandbox", 3))
                        {
                            cmod->cmod_flags |= CMOD_SANDBOX;
                            continue;
                        }
!                       if (!checkforcmd_noparen(&eap->cmd, "silent", 3))
                            break;
                        cmod->cmod_flags |= CMOD_SILENT;
                        if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1]))
***************
*** 2906,2912 ****
                        }
                        continue;
  
!           case 't':   if (checkforcmd(&p, "tab", 3))
                        {
                            if (!skip_only)
                            {
--- 2958,2964 ----
                        }
                        continue;
  
!           case 't':   if (checkforcmd_noparen(&p, "tab", 3))
                        {
                            if (!skip_only)
                            {
***************
*** 2928,2949 ****
                            eap->cmd = p;
                            continue;
                        }
!                       if (!checkforcmd(&eap->cmd, "topleft", 2))
                            break;
                        cmod->cmod_split |= WSP_TOP;
                        continue;
  
!           case 'u':   if (!checkforcmd(&eap->cmd, "unsilent", 3))
                            break;
                        cmod->cmod_flags |= CMOD_UNSILENT;
                        continue;
  
!           case 'v':   if (checkforcmd(&eap->cmd, "vertical", 4))
                        {
                            cmod->cmod_split |= WSP_VERT;
                            continue;
                        }
!                       if (checkforcmd(&eap->cmd, "vim9cmd", 4))
                        {
                            if (ends_excmd2(p, eap->cmd))
                            {
--- 2980,3001 ----
                            eap->cmd = p;
                            continue;
                        }
!                       if (!checkforcmd_noparen(&eap->cmd, "topleft", 2))
                            break;
                        cmod->cmod_split |= WSP_TOP;
                        continue;
  
!           case 'u':   if (!checkforcmd_noparen(&eap->cmd, "unsilent", 3))
                            break;
                        cmod->cmod_flags |= CMOD_UNSILENT;
                        continue;
  
!           case 'v':   if (checkforcmd_noparen(&eap->cmd, "vertical", 4))
                        {
                            cmod->cmod_split |= WSP_VERT;
                            continue;
                        }
!                       if (checkforcmd_noparen(&eap->cmd, "vim9cmd", 4))
                        {
                            if (ends_excmd2(p, eap->cmd))
                            {
***************
*** 2954,2960 ****
                            cmod->cmod_flags |= CMOD_VIM9CMD;
                            continue;
                        }
!                       if (!checkforcmd(&p, "verbose", 4))
                            break;
                        if (vim_isdigit(*eap->cmd))
                            cmod->cmod_verbose = atoi((char *)eap->cmd);
--- 3006,3012 ----
                            cmod->cmod_flags |= CMOD_VIM9CMD;
                            continue;
                        }
!                       if (!checkforcmd_noparen(&p, "verbose", 4))
                            break;
                        if (vim_isdigit(*eap->cmd))
                            cmod->cmod_verbose = atoi((char *)eap->cmd);
***************
*** 3252,3280 ****
  }
  
  /*
-  * Check for an Ex command with optional tail.
-  * If there is a match advance "pp" to the argument and return TRUE.
-  */
-     int
- checkforcmd(
-     char_u    **pp,           // start of command
-     char      *cmd,           // name of command
-     int               len)            // required length
- {
-     int               i;
- 
-     for (i = 0; cmd[i] != NUL; ++i)
-       if (((char_u *)cmd)[i] != (*pp)[i])
-           break;
-     if (i >= len && !isalpha((*pp)[i]) && (*pp)[i] != '_')
-     {
-       *pp = skipwhite(*pp + i);
-       return TRUE;
-     }
-     return FALSE;
- }
- 
- /*
   * Append "cmd" to the error message in IObuff.
   * Takes care of limiting the length and handling 0xa0, which would be
   * invisible otherwise.
--- 3304,3309 ----
*** ../vim-8.2.2667/src/testdir/test_vim9_builtin.vim   2021-03-27 
21:23:27.064153032 +0100
--- src/testdir/test_vim9_builtin.vim   2021-03-27 22:17:25.907777219 +0100
***************
*** 142,156 ****
    CheckFeature browse
  
    var lines =<< trim END
!       call browse(1, 2, 3, 4)
    END
    CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 2')
    lines =<< trim END
!       call browse(1, 'title', 3, 4)
    END
    CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 3')
    lines =<< trim END
!       call browse(1, 'title', 'dir', 4)
    END
    CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 4')
  enddef
--- 142,156 ----
    CheckFeature browse
  
    var lines =<< trim END
!       browse(1, 2, 3, 4)
    END
    CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 2')
    lines =<< trim END
!       browse(1, 'title', 3, 4)
    END
    CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 3')
    lines =<< trim END
!       browse(1, 'title', 'dir', 4)
    END
    CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 4')
  enddef
***************
*** 236,244 ****
      CheckFeature dialog_con
    endif
  
!   assert_fails('call confirm(true)', 'E1174')
!   assert_fails('call confirm("yes", true)', 'E1174')
!   assert_fails('call confirm("yes", "maybe", 2, true)', 'E1174')
  enddef
  
  def Test_copy_return_type()
--- 236,244 ----
      CheckFeature dialog_con
    endif
  
!   assert_fails('confirm(true)', 'E1174')
!   assert_fails('confirm("yes", true)', 'E1174')
!   assert_fails('confirm("yes", "maybe", 2, true)', 'E1174')
  enddef
  
  def Test_copy_return_type()
*** ../vim-8.2.2667/src/version.c       2021-03-27 22:07:21.529728904 +0100
--- src/version.c       2021-03-27 22:16:09.020035029 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2668,
  /**/

-- 
What a wonderfully exciting cough!  Do you mind if I join you?
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202103272120.12RLKonD704180%40masaka.moolenaar.net.

Raspunde prin e-mail lui