From bad5b2f8cf03c6cec690e29b937aac2bb7f2d1e0 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 18 Jun 2017 15:53:53 +0300 Subject: eval: Error out when there is something after :endfunction Ref #6844 --- src/nvim/eval.c | 10 +++++++++- src/nvim/globals.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index baa61a26bc..c424cfcd80 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -19842,8 +19842,16 @@ void ex_function(exarg_T *eap) /* Check for "endfunction". */ if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) { - if (line_arg == NULL) + if (*p == '!') { + p++; + } + p += strspn((const char *)p, " \t\r\n"); + if (*p != NUL && *p != '"') { + emsgf(_(e_trailing2), p); + } + if (line_arg == NULL) { xfree(theline); + } break; } diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 840be928c8..6d1bd1de12 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -1131,6 +1131,7 @@ EXTERN char_u e_longname[] INIT(= N_("E75: Name too long")); EXTERN char_u e_toomsbra[] INIT(= N_("E76: Too many [")); EXTERN char_u e_toomany[] INIT(= N_("E77: Too many file names")); EXTERN char_u e_trailing[] INIT(= N_("E488: Trailing characters")); +EXTERN char_u e_trailing2[] INIT(= N_("E488: Trailing characters: %s")); EXTERN char_u e_umark[] INIT(= N_("E78: Unknown mark")); EXTERN char_u e_wildexpand[] INIT(= N_("E79: Cannot expand wildcards")); EXTERN char_u e_winheight[] INIT(= N_( -- cgit From 60c025267265ba4bfc2abd34ea02b13bd5c0e63f Mon Sep 17 00:00:00 2001 From: ZyX Date: Tue, 20 Jun 2017 17:36:56 +0300 Subject: eval: Allow running next command after :endfunction This will still error out on `:endfunction | next`, but defining many functions in one `:execute` should be possible. --- src/nvim/eval.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index c424cfcd80..18aa5bf763 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -19765,10 +19765,12 @@ void ex_function(exarg_T *eap) /* When there is a line break use what follows for the function body. * Makes 'exe "func Test()\n...\nendfunc"' work. */ - if (*p == '\n') + const char *const end = (const char *)p + STRLEN(p); + if (*p == '\n') { line_arg = p + 1; - else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) - EMSG(_(e_trailing)); + } else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) { + emsgf(_(e_trailing)); + } /* * Read the body of the function, until ":endfunction" is found. @@ -19845,12 +19847,26 @@ void ex_function(exarg_T *eap) if (*p == '!') { p++; } - p += strspn((const char *)p, " \t\r\n"); - if (*p != NUL && *p != '"') { + const char *const comment_start = strchr((const char *)p, '"'); + const char *const endfunc_end = (comment_start + ? strchr(comment_start, '\n') + : strpbrk((const char *)p, "\n|")); + p = (endfunc_end + ? (char_u *)endfunc_end + : p + STRLEN(p)); + if (*p == '|') { emsgf(_(e_trailing2), p); + if (line_arg == NULL) { + xfree(theline); + } + goto erret; } if (line_arg == NULL) { xfree(theline); + } else { + if ((const char *)p < end) { + eap->nextcmd = p + 1; + } } break; } -- cgit