]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.4948: cannot use Perl heredoc in nested :def function v8.2.4948
authorBram Moolenaar <Bram@vim.org>
Fri, 13 May 2022 12:50:36 +0000 (13:50 +0100)
committerBram Moolenaar <Bram@vim.org>
Fri, 13 May 2022 12:50:36 +0000 (13:50 +0100)
Problem:    Cannot use Perl heredoc in nested :def function. (Virginia
            Senioria)
Solution:   Only concatenate heredoc lines when not in a nested function.
            (closes #10415)

src/testdir/test_vim9_func.vim
src/userfunc.c
src/version.c

index 14d0bce6f510d2d5fd3bc64fc737cedae1cdf861..30ff1ef236e95e1584fe74fa56e21cfe9c96a608 100644 (file)
@@ -4155,5 +4155,23 @@ if has('lua')
   enddef
 endif
 
+if has('perl')
+  def Test_perl_heredoc_nested()
+    var lines =<< trim END
+        vim9script
+        def F(): string
+            def G(): string
+                perl << EOF
+        EOF
+                return 'done'
+            enddef
+            return G()
+        enddef
+        assert_equal('done', F())
+    END
+    v9.CheckScriptSuccess(lines)
+  enddef
+endif
+
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index 8d82beb7eb3a6f8cc16b4d6101c1e7c76bccaf63..42e285fca1765e3dc5ae72cbf5a7d1be8a7b8407 100644 (file)
@@ -1051,53 +1051,57 @@ get_function_body(
                    skip_until = vim_strnsave(p, skiptowhite(p) - p);
                getline_options = GETLINE_NONE;
                is_heredoc = TRUE;
-               if (eap->cmdidx == CMD_def)
+               if (eap->cmdidx == CMD_def && nesting == 0)
                    heredoc_concat_len = newlines->ga_len + 1;
            }
 
-           // Check for ":cmd v =<< [trim] EOF"
-           //       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)
+           if (!is_heredoc)
            {
-               int found = (eap->cmdidx == CMD_def && arg[0] == '='
+               // Check for ":cmd v =<< [trim] EOF"
+               //       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)
+                   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))))
                    {
-                       if (STRNCMP(p, "trim", 4) == 0)
-                       {
-                           // Ignore leading white space.
-                           p = skipwhite(p + 4);
-                           heredoc_trimmed = vim_strnsave(theline,
-                                   skipwhite(theline) - theline);
-                           continue;
-                       }
-                       if (STRNCMP(p, "eval", 4) == 0)
+                       p = skipwhite(arg + 3);
+                       while (TRUE)
                        {
-                           // Ignore leading white space.
-                           p = skipwhite(p + 4);
-                           continue;
+                           if (STRNCMP(p, "trim", 4) == 0)
+                           {
+                               // Ignore leading white space.
+                               p = skipwhite(p + 4);
+                               heredoc_trimmed = vim_strnsave(theline,
+                                       skipwhite(theline) - theline);
+                               continue;
+                           }
+                           if (STRNCMP(p, "eval", 4) == 0)
+                           {
+                               // Ignore leading white space.
+                               p = skipwhite(p + 4);
+                               continue;
+                           }
+                           break;
                        }
-                       break;
+                       skip_until = vim_strnsave(p, skiptowhite(p) - p);
+                       getline_options = GETLINE_NONE;
+                       is_heredoc = TRUE;
                    }
-                   skip_until = vim_strnsave(p, skiptowhite(p) - p);
-                   getline_options = GETLINE_NONE;
-                   is_heredoc = TRUE;
                }
            }
        }
index 196537359bcf790bd811b1b6338c890a6281fe0f..aaa1e02921ddc4267cd6fede5643a9df24882831 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4948,
 /**/
     4947,
 /**/