]> granicus.if.org Git - vim/commitdiff
patch 8.2.2668: Vim9: omitting "call" for "confirm()" does not give an error v8.2.2668
authorBram Moolenaar <Bram@vim.org>
Sat, 27 Mar 2021 21:20:21 +0000 (22:20 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 27 Mar 2021 21:20:21 +0000 (22:20 +0100)
Problem:    Vim9: omitting "call" for "confirm()" does not give an error.
Solution:   Do not recognize a modifier followed by "(".

src/ex_docmd.c
src/testdir/test_vim9_builtin.vim
src/version.c

index 6a4650130d9c69d7941a60603c5cf1d0fe86ea7c..7a035972137905c4956dae7283a824e7fbc319f8 100644 (file)
@@ -2684,6 +2684,58 @@ ex_errmsg(char *msg, char_u *arg)
     return ex_error_buf;
 }
 
+/*
+ * 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
@@ -2770,51 +2822,51 @@ parse_command_modifiers(
        switch (*p)
        {
            // When adding an entry, also modify cmd_exists().
-           case 'a':   if (!checkforcmd(&eap->cmd, "aboveleft", 3))
+           case 'a':   if (!checkforcmd_noparen(&eap->cmd, "aboveleft", 3))
                            break;
                        cmod->cmod_split |= WSP_ABOVE;
                        continue;
 
-           case 'b':   if (checkforcmd(&eap->cmd, "belowright", 3))
+           case 'b':   if (checkforcmd_noparen(&eap->cmd, "belowright", 3))
                        {
                            cmod->cmod_split |= WSP_BELOW;
                            continue;
                        }
-                       if (checkforcmd(&eap->cmd, "browse", 3))
+                       if (checkforcmd_opt(&eap->cmd, "browse", 3, TRUE))
                        {
 #ifdef FEAT_BROWSE_CMD
                            cmod->cmod_flags |= CMOD_BROWSE;
 #endif
                            continue;
                        }
-                       if (!checkforcmd(&eap->cmd, "botright", 2))
+                       if (!checkforcmd_noparen(&eap->cmd, "botright", 2))
                            break;
                        cmod->cmod_split |= WSP_BOT;
                        continue;
 
-           case 'c':   if (!checkforcmd(&eap->cmd, "confirm", 4))
+           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(&eap->cmd, "keepmarks", 3))
+           case 'k':   if (checkforcmd_noparen(&eap->cmd, "keepmarks", 3))
                        {
                            cmod->cmod_flags |= CMOD_KEEPMARKS;
                            continue;
                        }
-                       if (checkforcmd(&eap->cmd, "keepalt", 5))
+                       if (checkforcmd_noparen(&eap->cmd, "keepalt", 5))
                        {
                            cmod->cmod_flags |= CMOD_KEEPALT;
                            continue;
                        }
-                       if (checkforcmd(&eap->cmd, "keeppatterns", 5))
+                       if (checkforcmd_noparen(&eap->cmd, "keeppatterns", 5))
                        {
                            cmod->cmod_flags |= CMOD_KEEPPATTERNS;
                            continue;
                        }
-                       if (!checkforcmd(&eap->cmd, "keepjumps", 5))
+                       if (!checkforcmd_noparen(&eap->cmd, "keepjumps", 5))
                            break;
                        cmod->cmod_flags |= CMOD_KEEPJUMPS;
                        continue;
@@ -2823,7 +2875,7 @@ parse_command_modifiers(
                        {
                            char_u *reg_pat;
 
-                           if (!checkforcmd(&p, "filter", 4)
+                           if (!checkforcmd_noparen(&p, "filter", 4)
                                                || *p == NUL || ends_excmd(*p))
                                break;
                            if (*p == '!')
@@ -2857,45 +2909,45 @@ parse_command_modifiers(
                        }
 
                        // ":hide" and ":hide | cmd" are not modifiers
-           case 'h':   if (p != eap->cmd || !checkforcmd(&p, "hide", 3)
+           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(&eap->cmd, "lockmarks", 3))
+           case 'l':   if (checkforcmd_noparen(&eap->cmd, "lockmarks", 3))
                        {
                            cmod->cmod_flags |= CMOD_LOCKMARKS;
                            continue;
                        }
 
-                       if (!checkforcmd(&eap->cmd, "leftabove", 5))
+                       if (!checkforcmd_noparen(&eap->cmd, "leftabove", 5))
                            break;
                        cmod->cmod_split |= WSP_ABOVE;
                        continue;
 
-           case 'n':   if (checkforcmd(&eap->cmd, "noautocmd", 3))
+           case 'n':   if (checkforcmd_noparen(&eap->cmd, "noautocmd", 3))
                        {
                            cmod->cmod_flags |= CMOD_NOAUTOCMD;
                            continue;
                        }
-                       if (!checkforcmd(&eap->cmd, "noswapfile", 3))
+                       if (!checkforcmd_noparen(&eap->cmd, "noswapfile", 3))
                            break;
                        cmod->cmod_flags |= CMOD_NOSWAPFILE;
                        continue;
 
-           case 'r':   if (!checkforcmd(&eap->cmd, "rightbelow", 6))
+           case 'r':   if (!checkforcmd_noparen(&eap->cmd, "rightbelow", 6))
                            break;
                        cmod->cmod_split |= WSP_BELOW;
                        continue;
 
-           case 's':   if (checkforcmd(&eap->cmd, "sandbox", 3))
+           case 's':   if (checkforcmd_noparen(&eap->cmd, "sandbox", 3))
                        {
                            cmod->cmod_flags |= CMOD_SANDBOX;
                            continue;
                        }
-                       if (!checkforcmd(&eap->cmd, "silent", 3))
+                       if (!checkforcmd_noparen(&eap->cmd, "silent", 3))
                            break;
                        cmod->cmod_flags |= CMOD_SILENT;
                        if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1]))
@@ -2906,7 +2958,7 @@ parse_command_modifiers(
                        }
                        continue;
 
-           case 't':   if (checkforcmd(&p, "tab", 3))
+           case 't':   if (checkforcmd_noparen(&p, "tab", 3))
                        {
                            if (!skip_only)
                            {
@@ -2928,22 +2980,22 @@ parse_command_modifiers(
                            eap->cmd = p;
                            continue;
                        }
-                       if (!checkforcmd(&eap->cmd, "topleft", 2))
+                       if (!checkforcmd_noparen(&eap->cmd, "topleft", 2))
                            break;
                        cmod->cmod_split |= WSP_TOP;
                        continue;
 
-           case 'u':   if (!checkforcmd(&eap->cmd, "unsilent", 3))
+           case 'u':   if (!checkforcmd_noparen(&eap->cmd, "unsilent", 3))
                            break;
                        cmod->cmod_flags |= CMOD_UNSILENT;
                        continue;
 
-           case 'v':   if (checkforcmd(&eap->cmd, "vertical", 4))
+           case 'v':   if (checkforcmd_noparen(&eap->cmd, "vertical", 4))
                        {
                            cmod->cmod_split |= WSP_VERT;
                            continue;
                        }
-                       if (checkforcmd(&eap->cmd, "vim9cmd", 4))
+                       if (checkforcmd_noparen(&eap->cmd, "vim9cmd", 4))
                        {
                            if (ends_excmd2(p, eap->cmd))
                            {
@@ -2954,7 +3006,7 @@ parse_command_modifiers(
                            cmod->cmod_flags |= CMOD_VIM9CMD;
                            continue;
                        }
-                       if (!checkforcmd(&p, "verbose", 4))
+                       if (!checkforcmd_noparen(&p, "verbose", 4))
                            break;
                        if (vim_isdigit(*eap->cmd))
                            cmod->cmod_verbose = atoi((char *)eap->cmd);
@@ -3251,29 +3303,6 @@ parse_cmd_address(exarg_T *eap, char **errormsg, int silent)
     return OK;
 }
 
-/*
- * 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
index eba5ff6a418ed0b62ccbed43656e833515c9c7ca..73251c0baceb67ca3349fffa8eb8c444d16f2155 100644 (file)
@@ -142,15 +142,15 @@ def Test_browse()
   CheckFeature browse
 
   var lines =<< trim END
-      call browse(1, 2, 3, 4)
+      browse(1, 2, 3, 4)
   END
   CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 2')
   lines =<< trim END
-      call browse(1, 'title', 3, 4)
+      browse(1, 'title', 3, 4)
   END
   CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 3')
   lines =<< trim END
-      call browse(1, 'title', 'dir', 4)
+      browse(1, 'title', 'dir', 4)
   END
   CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 4')
 enddef
@@ -236,9 +236,9 @@ def Test_confirm()
     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')
+  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()
index a5a00793f1b8f5fb25637072f6bd04b92cfab368..716f41ea72867a3837002fae3b58c00895e1c7da 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2668,
 /**/
     2667,
 /**/