0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.2.2332: Vim9: missing :endif not reported when using :windo

Problem:    Vim9: missing :endif not reported when using :windo.
Solution:   Pass a getline function to do_cmdline(). (closes #7650)
This commit is contained in:
Bram Moolenaar
2021-01-11 22:16:30 +01:00
parent 082517570d
commit 9567efa1b4
5 changed files with 62 additions and 42 deletions

View File

@@ -1019,30 +1019,6 @@ ex_options(
/* /*
* ":source" and associated commands. * ":source" and associated commands.
*/ */
/*
* Structure used to store info for each sourced file.
* It is shared between do_source() and getsourceline().
* This is required, because it needs to be handed to do_cmdline() and
* sourcing can be done recursively.
*/
struct source_cookie
{
FILE *fp; // opened file for sourcing
char_u *nextline; // if not NULL: line that was read ahead
linenr_T sourcing_lnum; // line number of the source file
int finished; // ":finish" used
#ifdef USE_CRNL
int fileformat; // EOL_UNKNOWN, EOL_UNIX or EOL_DOS
int error; // TRUE if LF found after CR-LF
#endif
#ifdef FEAT_EVAL
linenr_T breakpoint; // next line with breakpoint or zero
char_u *fname; // name of sourced file
int dbg_tick; // debug_tick when breakpoint was set
int level; // top nesting level of sourced file
#endif
vimconv_T conv; // type of conversion
};
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
/* /*
@@ -1051,7 +1027,7 @@ struct source_cookie
linenr_T * linenr_T *
source_breakpoint(void *cookie) source_breakpoint(void *cookie)
{ {
return &((struct source_cookie *)cookie)->breakpoint; return &((source_cookie_T *)cookie)->breakpoint;
} }
/* /*
@@ -1060,7 +1036,7 @@ source_breakpoint(void *cookie)
int * int *
source_dbg_tick(void *cookie) source_dbg_tick(void *cookie)
{ {
return &((struct source_cookie *)cookie)->dbg_tick; return &((source_cookie_T *)cookie)->dbg_tick;
} }
/* /*
@@ -1069,7 +1045,7 @@ source_dbg_tick(void *cookie)
int int
source_level(void *cookie) source_level(void *cookie)
{ {
return ((struct source_cookie *)cookie)->level; return ((source_cookie_T *)cookie)->level;
} }
/* /*
@@ -1079,7 +1055,7 @@ source_level(void *cookie)
char_u * char_u *
source_nextline(void *cookie) source_nextline(void *cookie)
{ {
return ((struct source_cookie *)cookie)->nextline; return ((source_cookie_T *)cookie)->nextline;
} }
#endif #endif
@@ -1130,7 +1106,7 @@ do_source(
int is_vimrc, // DOSO_ value int is_vimrc, // DOSO_ value
int *ret_sid UNUSED) int *ret_sid UNUSED)
{ {
struct source_cookie cookie; source_cookie_T cookie;
char_u *p; char_u *p;
char_u *fname_exp; char_u *fname_exp;
char_u *firstline = NULL; char_u *firstline = NULL;
@@ -1613,12 +1589,12 @@ get_sourced_lnum(
void *cookie) void *cookie)
{ {
return fgetline == getsourceline return fgetline == getsourceline
? ((struct source_cookie *)cookie)->sourcing_lnum ? ((source_cookie_T *)cookie)->sourcing_lnum
: SOURCING_LNUM; : SOURCING_LNUM;
} }
static char_u * static char_u *
get_one_sourceline(struct source_cookie *sp) get_one_sourceline(source_cookie_T *sp)
{ {
garray_T ga; garray_T ga;
int len; int len;
@@ -1736,7 +1712,7 @@ getsourceline(
int indent UNUSED, int indent UNUSED,
getline_opt_T options) getline_opt_T options)
{ {
struct source_cookie *sp = (struct source_cookie *)cookie; source_cookie_T *sp = (source_cookie_T *)cookie;
char_u *line; char_u *line;
char_u *p; char_u *p;
int do_vim9_all = in_vim9script() int do_vim9_all = in_vim9script()
@@ -1761,8 +1737,8 @@ getsourceline(
SOURCING_LNUM = sp->sourcing_lnum + 1; SOURCING_LNUM = sp->sourcing_lnum + 1;
// Get current line. If there is a read-ahead line, use it, otherwise get // Get current line. If there is a read-ahead line, use it, otherwise get
// one now. // one now. "fp" is NULL if actually using a string.
if (sp->finished) if (sp->finished || sp->fp == NULL)
line = NULL; line = NULL;
else if (sp->nextline == NULL) else if (sp->nextline == NULL)
line = get_one_sourceline(sp); line = get_one_sourceline(sp);
@@ -1880,7 +1856,7 @@ getsourceline(
void void
ex_scriptencoding(exarg_T *eap) ex_scriptencoding(exarg_T *eap)
{ {
struct source_cookie *sp; source_cookie_T *sp;
char_u *name; char_u *name;
if (!getline_equal(eap->getline, eap->cookie, getsourceline)) if (!getline_equal(eap->getline, eap->cookie, getsourceline))
@@ -1899,7 +1875,7 @@ ex_scriptencoding(exarg_T *eap)
name = eap->arg; name = eap->arg;
// Setup for conversion from the specified encoding to 'encoding'. // Setup for conversion from the specified encoding to 'encoding'.
sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie); sp = (source_cookie_T *)getline_cookie(eap->getline, eap->cookie);
convert_setup(&sp->conv, name, p_enc); convert_setup(&sp->conv, name, p_enc);
if (name != eap->arg) if (name != eap->arg)
@@ -1963,7 +1939,7 @@ do_finish(exarg_T *eap, int reanimate)
int idx; int idx;
if (reanimate) if (reanimate)
((struct source_cookie *)getline_cookie(eap->getline, ((source_cookie_T *)getline_cookie(eap->getline,
eap->cookie))->finished = FALSE; eap->cookie))->finished = FALSE;
// Cleanup (and inactivate) conditionals, but stop when a try conditional // Cleanup (and inactivate) conditionals, but stop when a try conditional
@@ -1977,7 +1953,7 @@ do_finish(exarg_T *eap, int reanimate)
report_make_pending(CSTP_FINISH, NULL); report_make_pending(CSTP_FINISH, NULL);
} }
else else
((struct source_cookie *)getline_cookie(eap->getline, ((source_cookie_T *)getline_cookie(eap->getline,
eap->cookie))->finished = TRUE; eap->cookie))->finished = TRUE;
} }
@@ -1993,7 +1969,7 @@ source_finished(
void *cookie) void *cookie)
{ {
return (getline_equal(fgetline, cookie, getsourceline) return (getline_equal(fgetline, cookie, getsourceline)
&& ((struct source_cookie *)getline_cookie( && ((source_cookie_T *)getline_cookie(
fgetline, cookie))->finished); fgetline, cookie))->finished);
} }

View File

@@ -4300,6 +4300,32 @@ typedef struct
int sa_wrapped; // search wrapped around int sa_wrapped; // search wrapped around
} searchit_arg_T; } searchit_arg_T;
/*
* Cookie used by getsourceline().
*/
/*
* Cookie used to store info for each sourced file.
* It is shared between do_source() and getsourceline().
* This is passed to do_cmdline().
*/
typedef struct {
FILE *fp; // opened file for sourcing
char_u *nextline; // if not NULL: line that was read ahead
linenr_T sourcing_lnum; // line number of the source file
int finished; // ":finish" used
#ifdef USE_CRNL
int fileformat; // EOL_UNKNOWN, EOL_UNIX or EOL_DOS
int error; // TRUE if LF found after CR-LF
#endif
#ifdef FEAT_EVAL
linenr_T breakpoint; // next line with breakpoint or zero
char_u *fname; // name of sourced file
int dbg_tick; // debug_tick when breakpoint was set
int level; // top nesting level of sourced file
#endif
vimconv_T conv; // type of conversion
} source_cookie_T;
#define WRITEBUFSIZE 8192 // size of normal write buffer #define WRITEBUFSIZE 8192 // size of normal write buffer

View File

@@ -921,4 +921,11 @@ def Test_wincmd()
close close
enddef enddef
def Test_windo_missing_endif()
var lines =<< trim END
windo if 1
END
CheckDefExecFailure(lines, 'E171:', 1)
enddef
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2332,
/**/ /**/
2331, 2331,
/**/ /**/

View File

@@ -1382,9 +1382,18 @@ call_def_function(
// execute Ex command line // execute Ex command line
case ISN_EXEC: case ISN_EXEC:
{ {
source_cookie_T cookie;
SOURCING_LNUM = iptr->isn_lnum; SOURCING_LNUM = iptr->isn_lnum;
do_cmdline_cmd(iptr->isn_arg.string); // Pass getsourceline to get an error for a missing ":end"
if (did_emsg) // command.
CLEAR_FIELD(cookie);
cookie.sourcing_lnum = iptr->isn_lnum - 1;
if (do_cmdline(iptr->isn_arg.string,
getsourceline, &cookie,
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED)
== FAIL
|| did_emsg)
goto on_error; goto on_error;
} }
break; break;