patch 9.1.1074: Strange error when heredoc marker starts with "trim"

Problem:  Strange error when heredoc marker starts with "trim".
Solution: Check for whitespace after "trim" or "eval" (zeertzjq)

For :python3 etc., a heredoc marker that starts with a lower-case letter
is valid, and when it starts with "trim" it works in a script but not in
a function, and this PR makes it works in a function.
For :let, a heredoc marker that starts with a lower-case letter is not
valid, but when it starts with "trim" or "eval" the error can be a bit
confusing in a function, and this PR make it less confusing.

closes: #16574

Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/testdir/test_let.vim b/src/testdir/test_let.vim
index 2aba1d3..e31b514 100644
--- a/src/testdir/test_let.vim
+++ b/src/testdir/test_let.vim
@@ -435,6 +435,24 @@
     call assert_report('Caught exception: ' .. v:exception)
   endtry
 
+  try
+    let v =<< trim trimm
+    trimm
+    call assert_report('No exception thrown')
+  catch /E221:/
+  catch
+    call assert_report('Caught exception: ' .. v:exception)
+  endtry
+
+  try
+    let v =<< trim trim evall
+    evall
+    call assert_report('No exception thrown')
+  catch /E221:/
+  catch
+    call assert_report('Caught exception: ' .. v:exception)
+  endtry
+
   let text =<< trim END
   func WrongSyntax()
     let v =<< that there
diff --git a/src/testdir/test_lua.vim b/src/testdir/test_lua.vim
index 5225ce8..043531a 100644
--- a/src/testdir/test_lua.vim
+++ b/src/testdir/test_lua.vim
@@ -934,7 +934,10 @@
   lua << trim eof
     vim.command('let s ..= "E"')
   eof
-  call assert_equal('ABCDE', s)
+  lua << trimm
+vim.command('let s ..= "F"')
+trimm
+  call assert_equal('ABCDEF', s)
 endfunc
 
 " Test for adding, accessing and removing global variables using the vim.g
diff --git a/src/testdir/test_perl.vim b/src/testdir/test_perl.vim
index 721179c..31329ca 100644
--- a/src/testdir/test_perl.vim
+++ b/src/testdir/test_perl.vim
@@ -359,7 +359,10 @@
   perl << trim eof
     VIM::DoCommand('let s ..= "E"')
   eof
-  call assert_equal('ABCDE', s)
+  perl << trimm
+VIM::DoCommand('let s ..= "F"')
+trimm
+  call assert_equal('ABCDEF', s)
 endfunc
 
 func Test_perl_in_sandbox()
diff --git a/src/testdir/test_python2.vim b/src/testdir/test_python2.vim
index de5f607..4ba0f8e 100644
--- a/src/testdir/test_python2.vim
+++ b/src/testdir/test_python2.vim
@@ -263,7 +263,10 @@
   python << trim eof
     s+='E'
   eof
-  call assert_equal('ABCDE', pyxeval('s'))
+python << trimm
+s+='F'
+trimm
+  call assert_equal('ABCDEF', pyxeval('s'))
 endfunc
 
 " Test for the buffer range object
diff --git a/src/testdir/test_python3.vim b/src/testdir/test_python3.vim
index 20f9dc6..c044954 100644
--- a/src/testdir/test_python3.vim
+++ b/src/testdir/test_python3.vim
@@ -467,7 +467,10 @@
   python3 << trim eof
     s+='E'
   eof
-  call assert_equal('ABCDE', pyxeval('s'))
+  python3 << trimm
+s+='F'
+trimm
+  call assert_equal('ABCDEF', pyxeval('s'))
 endfunc
 
 " Test for the buffer range object
diff --git a/src/testdir/test_pyx2.vim b/src/testdir/test_pyx2.vim
index 781bb41..68f1901 100644
--- a/src/testdir/test_pyx2.vim
+++ b/src/testdir/test_pyx2.vim
@@ -140,7 +140,10 @@
   pyx << trim eof
     result+='E'
   eof
-  call assert_equal('ABCDE', pyxeval('result'))
+  pyx << trimm
+result+='F'
+trimm
+  call assert_equal('ABCDEF', pyxeval('result'))
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_pyx3.vim b/src/testdir/test_pyx3.vim
index b34fdcb..b02f447 100644
--- a/src/testdir/test_pyx3.vim
+++ b/src/testdir/test_pyx3.vim
@@ -139,7 +139,10 @@
   pyx << trim eof
     result+='E'
   eof
-  call assert_equal('ABCDE', pyxeval('result'))
+  pyx << trimm
+result+='F'
+trimm
+  call assert_equal('ABCDEF', pyxeval('result'))
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_ruby.vim b/src/testdir/test_ruby.vim
index cc5f419..d4ff8e0 100644
--- a/src/testdir/test_ruby.vim
+++ b/src/testdir/test_ruby.vim
@@ -446,7 +446,10 @@
   ruby << trim eof
     Vim.command('let s ..= "E"')
   eof
-  call assert_equal('ABCDE', s)
+ruby << trimm
+Vim.command('let s ..= "F"')
+trimm
+  call assert_equal('ABCDEF', s)
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/userfunc.c b/src/userfunc.c
index a60eeb2..b7d2752 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -1322,7 +1322,8 @@
 	    {
 		// ":python <<" continues until a dot, like ":append"
 		p = skipwhite(arg + 2);
-		if (STRNCMP(p, "trim", 4) == 0)
+		if (STRNCMP(p, "trim", 4) == 0
+			&& (p[4] == NUL || VIM_ISWHITE(p[4])))
 		{
 		    // Ignore leading white space.
 		    p = skipwhite(p + 4);
@@ -1367,20 +1368,21 @@
 		    current_sctx.sc_version = save_sc_version;
 		    if (arg != NULL && STRNCMP(arg, "=<<", 3) == 0)
 		    {
+			int has_trim = FALSE;
+
 			p = skipwhite(arg + 3);
 			while (TRUE)
 			{
-			    if (STRNCMP(p, "trim", 4) == 0)
+			    if (STRNCMP(p, "trim", 4) == 0
+				    && (p[4] == NUL || VIM_ISWHITE(p[4])))
 			    {
 				// Ignore leading white space.
 				p = skipwhite(p + 4);
-				heredoc_trimmedlen = skipwhite(theline) - theline;
-				heredoc_trimmed = vim_strnsave(theline, heredoc_trimmedlen);
-				if (heredoc_trimmed == NULL)
-				    heredoc_trimmedlen = 0;
+				has_trim = TRUE;
 				continue;
 			    }
-			    if (STRNCMP(p, "eval", 4) == 0)
+			    if (STRNCMP(p, "eval", 4) == 0
+				    && (p[4] == NUL || VIM_ISWHITE(p[4])))
 			    {
 				// Ignore leading white space.
 				p = skipwhite(p + 4);
@@ -1388,6 +1390,13 @@
 			    }
 			    break;
 			}
+			if (has_trim)
+			{
+			    heredoc_trimmedlen = skipwhite(theline) - theline;
+			    heredoc_trimmed = vim_strnsave(theline, heredoc_trimmedlen);
+			    if (heredoc_trimmed == NULL)
+				heredoc_trimmedlen = 0;
+			}
 			skip_until = vim_strnsave(p, skiptowhite(p) - p);
 			getline_options = GETLINE_NONE;
 			is_heredoc = TRUE;
diff --git a/src/version.c b/src/version.c
index add5959..545b635 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1074,
+/**/
     1073,
 /**/
     1072,