summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-01-01 18:43:51 +0100
committerBram Moolenaar <Bram@vim.org>2021-01-01 18:43:51 +0100
commit5178b1b02fc96f42d62199a4be9184c2aea8a49a (patch)
tree19f56b937a4af6ca509310d6b03a49aa830dd48c
parent69f7050cebb0f069d6e39571961b9bbe8531c69a (diff)
patch 8.2.2264: Vim9: no error for mismatched :endfunc or :enddefv8.2.2264
Problem: Vim9: no error for mismatched :endfunc or :enddef. Solution: Check for the mismatch. (issue #7582)
-rw-r--r--src/errors.h4
-rw-r--r--src/testdir/test_vim9_func.vim19
-rw-r--r--src/userfunc.c60
-rw-r--r--src/version.c2
4 files changed, 63 insertions, 22 deletions
diff --git a/src/errors.h b/src/errors.h
index 4b4245a1bd..6f4ac0e1a7 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -335,3 +335,7 @@ EXTERN char e_script_variable_invalid_after_reload_in_function_str[]
INIT(= N_("E1149: Script variable is invalid after reload in function %s"));
EXTERN char e_script_variable_type_changed[]
INIT(= N_("E1150: Script variable type changed"));
+EXTERN char e_mismatched_endfunction[]
+ INIT(= N_("E1151: Mismatched endfunction"));
+EXTERN char e_mismatched_enddef[]
+ INIT(= N_("E1152: Mismatched enddef"));
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index a2d1ed3e29..223b2fbda7 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -79,6 +79,25 @@ def Test_funcdepth_error()
set maxfuncdepth&
enddef
+def Test_endfunc_enddef()
+ var lines =<< trim END
+ def Test()
+ echo 'test'
+ endfunc
+ enddef
+ END
+ CheckScriptFailure(lines, 'E1151:', 3)
+
+ lines =<< trim END
+ def Test()
+ func Nested()
+ echo 'test'
+ enddef
+ enddef
+ END
+ CheckScriptFailure(lines, 'E1152:', 4)
+enddef
+
def ReturnString(): string
return 'string'
enddef
diff --git a/src/userfunc.c b/src/userfunc.c
index bc3dd0e9ae..f0877e1c3b 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -3404,35 +3404,51 @@ define_function(exarg_T *eap, char_u *name_arg)
// Check for "endfunction" or "enddef".
if (checkforcmd(&p, nesting_def[nesting]
- ? "enddef" : "endfunction", 4) && nesting-- == 0)
+ ? "enddef" : "endfunction", 4))
{
- char_u *nextcmd = NULL;
-
- if (*p == '|')
- nextcmd = p + 1;
- else if (line_arg != NULL && *skipwhite(line_arg) != NUL)
- nextcmd = line_arg;
- else if (*p != NUL && *p != '"' && p_verbose > 0)
- give_warning2(eap->cmdidx == CMD_def
- ? (char_u *)_("W1001: Text found after :enddef: %s")
- : (char_u *)_("W22: Text found after :endfunction: %s"),
- p, TRUE);
- if (nextcmd != NULL)
+ if (nesting-- == 0)
{
- // Another command follows. If the line came from "eap" we
- // can simply point into it, otherwise we need to change
- // "eap->cmdlinep".
- eap->nextcmd = nextcmd;
- if (line_to_free != NULL)
+ char_u *nextcmd = NULL;
+
+ if (*p == '|')
+ nextcmd = p + 1;
+ else if (line_arg != NULL && *skipwhite(line_arg) != NUL)
+ nextcmd = line_arg;
+ else if (*p != NUL && *p != '"' && p_verbose > 0)
+ give_warning2(eap->cmdidx == CMD_def
+ ? (char_u *)_("W1001: Text found after :enddef: %s")
+ : (char_u *)_("W22: Text found after :endfunction: %s"),
+ p, TRUE);
+ if (nextcmd != NULL)
{
- vim_free(*eap->cmdlinep);
- *eap->cmdlinep = line_to_free;
- line_to_free = NULL;
+ // Another command follows. If the line came from "eap"
+ // we can simply point into it, otherwise we need to
+ // change "eap->cmdlinep".
+ eap->nextcmd = nextcmd;
+ if (line_to_free != NULL)
+ {
+ vim_free(*eap->cmdlinep);
+ *eap->cmdlinep = line_to_free;
+ line_to_free = NULL;
+ }
}
+ break;
}
- break;
}
+ // Check for mismatched "endfunc" or "enddef".
+ // We don't check for "def" inside "func" thus we also can't check
+ // for "enddef".
+ // We continue to find the end of the function, although we might
+ // not find it.
+ else if (nesting_def[nesting])
+ {
+ if (checkforcmd(&p, "endfunction", 4))
+ emsg(_(e_mismatched_endfunction));
+ }
+ else if (eap->cmdidx == CMD_def && checkforcmd(&p, "enddef", 4))
+ emsg(_(e_mismatched_enddef));
+
// Increase indent inside "if", "while", "for" and "try", decrease
// at "end".
if (indent > 2 && (*p == '}' || STRNCMP(p, "end", 3) == 0))
diff --git a/src/version.c b/src/version.c
index 26c9d8bf8d..3fc3c01e1d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2264,
+/**/
2263,
/**/
2262,