vim-patch:8.1.1588: in :let-heredoc line continuation is recognized

Problem:    In :let-heredoc line continuation is recognized.
Solution:   Do not consume line continuation. (Ozaki Kiichi, closes vim/vim#4580)
e96a2498f9
This commit is contained in:
Jurica Bradaric 2019-09-23 21:19:26 +02:00
parent c84b39150f
commit 0586a4b512
11 changed files with 68 additions and 58 deletions

View File

@ -1887,7 +1887,7 @@ void ex_loadkeymap(exarg_T *eap)
// Get each line of the sourced file, break at the end. // Get each line of the sourced file, break at the end.
for (;;) { for (;;) {
line = eap->getline(0, eap->cookie, 0); line = eap->getline(0, eap->cookie, 0, true);
if (line == NULL) { if (line == NULL) {
break; break;

View File

@ -1561,7 +1561,7 @@ heredoc_get(exarg_T *eap, char_u *cmd)
for (;;) { for (;;) {
int i = 0; int i = 0;
char_u *theline = eap->getline(NUL, eap->cookie, 0); char_u *theline = eap->getline(NUL, eap->cookie, 0, false);
if (theline != NULL && indent_len > 0) { if (theline != NULL && indent_len > 0) {
// trim the indent matching the first line // trim the indent matching the first line
if (STRNCMP(theline, *eap->cmdlinep, indent_len) == 0) { if (STRNCMP(theline, *eap->cmdlinep, indent_len) == 0) {
@ -8734,7 +8734,7 @@ typedef struct {
const listitem_T *li; const listitem_T *li;
} GetListLineCookie; } GetListLineCookie;
static char_u *get_list_line(int c, void *cookie, int indent) static char_u *get_list_line(int c, void *cookie, int indent, bool do_concat)
{ {
GetListLineCookie *const p = (GetListLineCookie *)cookie; GetListLineCookie *const p = (GetListLineCookie *)cookie;
@ -21279,6 +21279,7 @@ void ex_function(exarg_T *eap)
hashitem_T *hi; hashitem_T *hi;
int sourcing_lnum_off; int sourcing_lnum_off;
bool show_block = false; bool show_block = false;
bool do_concat = true;
/* /*
* ":function" without argument: list functions. * ":function" without argument: list functions.
@ -21548,9 +21549,9 @@ void ex_function(exarg_T *eap)
} else { } else {
xfree(line_to_free); xfree(line_to_free);
if (eap->getline == NULL) { if (eap->getline == NULL) {
theline = getcmdline(':', 0L, indent); theline = getcmdline(':', 0L, indent, do_concat);
} else { } else {
theline = eap->getline(':', eap->cookie, indent); theline = eap->getline(':', eap->cookie, indent, do_concat);
} }
line_to_free = theline; line_to_free = theline;
} }
@ -21580,6 +21581,7 @@ void ex_function(exarg_T *eap)
if (STRCMP(p, skip_until) == 0) { if (STRCMP(p, skip_until) == 0) {
XFREE_CLEAR(skip_until); XFREE_CLEAR(skip_until);
XFREE_CLEAR(trimmed); XFREE_CLEAR(trimmed);
do_concat = true;
} }
} }
} else { } else {
@ -21699,6 +21701,7 @@ void ex_function(exarg_T *eap)
} else { } else {
skip_until = vim_strnsave(p, (int)(skiptowhite(p) - p)); skip_until = vim_strnsave(p, (int)(skiptowhite(p) - p));
} }
do_concat = false;
} }
} }
@ -23522,7 +23525,7 @@ char_u *get_return_cmd(void *rettv)
* Called by do_cmdline() to get the next line. * Called by do_cmdline() to get the next line.
* Returns allocated string, or NULL for end of function. * Returns allocated string, or NULL for end of function.
*/ */
char_u *get_func_line(int c, void *cookie, int indent) char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
{ {
funccall_T *fcp = (funccall_T *)cookie; funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func; ufunc_T *fp = fcp->func;

View File

@ -2767,7 +2767,7 @@ void ex_append(exarg_T *eap)
State = CMDLINE; State = CMDLINE;
theline = eap->getline( theline = eap->getline(
eap->cstack->cs_looplevel > 0 ? -1 : eap->cstack->cs_looplevel > 0 ? -1 :
NUL, eap->cookie, indent); NUL, eap->cookie, indent, true);
State = save_State; State = save_State;
} }
lines_left = Rows - 1; lines_left = Rows - 1;
@ -3630,7 +3630,7 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout,
for (; i <= (long)ec; ++i) for (; i <= (long)ec; ++i)
msg_putchar('^'); msg_putchar('^');
resp = getexmodeline('?', NULL, 0); resp = getexmodeline('?', NULL, 0, true);
if (resp != NULL) { if (resp != NULL) {
typed = *resp; typed = *resp;
xfree(resp); xfree(resp);

View File

@ -3218,7 +3218,7 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
cookie.conv.vc_type = CONV_NONE; // no conversion cookie.conv.vc_type = CONV_NONE; // no conversion
// Read the first line so we can check for a UTF-8 BOM. // Read the first line so we can check for a UTF-8 BOM.
firstline = getsourceline(0, (void *)&cookie, 0); firstline = getsourceline(0, (void *)&cookie, 0, true);
if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
&& firstline[1] == 0xbb && firstline[2] == 0xbf) { && firstline[1] == 0xbb && firstline[2] == 0xbf) {
// Found BOM; setup conversion, skip over BOM and recode the line. // Found BOM; setup conversion, skip over BOM and recode the line.
@ -3381,7 +3381,7 @@ void free_scriptnames(void)
/// ///
/// @return pointer to the line in allocated memory, or NULL for end-of-file or /// @return pointer to the line in allocated memory, or NULL for end-of-file or
/// some error. /// some error.
char_u *getsourceline(int c, void *cookie, int indent) char_u *getsourceline(int c, void *cookie, int indent, bool do_concat)
{ {
struct source_cookie *sp = (struct source_cookie *)cookie; struct source_cookie *sp = (struct source_cookie *)cookie;
char_u *line; char_u *line;
@ -3412,7 +3412,7 @@ char_u *getsourceline(int c, void *cookie, int indent)
// Only concatenate lines starting with a \ when 'cpoptions' doesn't // Only concatenate lines starting with a \ when 'cpoptions' doesn't
// contain the 'C' flag. // contain the 'C' flag.
if (line != NULL && (vim_strchr(p_cpo, CPO_CONCAT) == NULL)) { if (line != NULL && do_concat && (vim_strchr(p_cpo, CPO_CONCAT) == NULL)) {
// compensate for the one line read-ahead // compensate for the one line read-ahead
sourcing_lnum--; sourcing_lnum--;

View File

@ -88,7 +88,7 @@ typedef struct exarg exarg_T;
typedef void (*ex_func_T)(exarg_T *eap); typedef void (*ex_func_T)(exarg_T *eap);
typedef char_u *(*LineGetter)(int, void *, int); typedef char_u *(*LineGetter)(int, void *, int, bool);
/// Structure for command definition. /// Structure for command definition.
typedef struct cmdname { typedef struct cmdname {

View File

@ -117,11 +117,11 @@ typedef struct {
* reads more lines that may come from the while/for loop. * reads more lines that may come from the while/for loop.
*/ */
struct loop_cookie { struct loop_cookie {
garray_T *lines_gap; /* growarray with line info */ garray_T *lines_gap; // growarray with line info
int current_line; /* last read line from growarray */ int current_line; // last read line from growarray
int repeating; /* TRUE when looping a second time */ int repeating; // TRUE when looping a second time
/* When "repeating" is FALSE use "getline" and "cookie" to get lines */ // When "repeating" is FALSE use "getline" and "cookie" to get lines
char_u *(*getline)(int, void *, int); char_u *(*getline)(int, void *, int, bool);
void *cookie; void *cookie;
}; };
@ -313,8 +313,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
struct msglist **saved_msg_list = NULL; struct msglist **saved_msg_list = NULL;
struct msglist *private_msg_list; struct msglist *private_msg_list;
/* "fgetline" and "cookie" passed to do_one_cmd() */ // "fgetline" and "cookie" passed to do_one_cmd()
char_u *(*cmd_getline)(int, void *, int); char_u *(*cmd_getline)(int, void *, int, bool);
void *cmd_cookie; void *cmd_cookie;
struct loop_cookie cmd_loop_cookie; struct loop_cookie cmd_loop_cookie;
void *real_cookie; void *real_cookie;
@ -507,17 +507,20 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
* Need to set msg_didout for the first line after an ":if", * Need to set msg_didout for the first line after an ":if",
* otherwise the ":if" will be overwritten. * otherwise the ":if" will be overwritten.
*/ */
if (count == 1 && getline_equal(fgetline, cookie, getexline)) if (count == 1 && getline_equal(fgetline, cookie, getexline)) {
msg_didout = TRUE; msg_didout = true;
if (fgetline == NULL || (next_cmdline = fgetline(':', cookie, }
if (fgetline == NULL
|| (next_cmdline = fgetline(':', cookie,
cstack.cs_idx < cstack.cs_idx <
0 ? 0 : (cstack.cs_idx + 1) * 2 0 ? 0 : (cstack.cs_idx + 1) * 2,
)) == NULL) { true)) == NULL) {
/* Don't call wait_return for aborted command line. The NULL // Don't call wait_return for aborted command line. The NULL
* returned for the end of a sourced file or executed function // returned for the end of a sourced file or executed function
* doesn't do this. */ // doesn't do this.
if (KeyTyped && !(flags & DOCMD_REPEAT)) if (KeyTyped && !(flags & DOCMD_REPEAT)) {
need_wait_return = FALSE; need_wait_return = false;
}
retval = FAIL; retval = FAIL;
break; break;
} }
@ -951,7 +954,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
/* /*
* Obtain a line when inside a ":while" or ":for" loop. * Obtain a line when inside a ":while" or ":for" loop.
*/ */
static char_u *get_loop_line(int c, void *cookie, int indent) static char_u *get_loop_line(int c, void *cookie, int indent, bool do_concat)
{ {
struct loop_cookie *cp = (struct loop_cookie *)cookie; struct loop_cookie *cp = (struct loop_cookie *)cookie;
wcmd_T *wp; wcmd_T *wp;
@ -961,11 +964,12 @@ static char_u *get_loop_line(int c, void *cookie, int indent)
if (cp->repeating) if (cp->repeating)
return NULL; /* trying to read past ":endwhile"/":endfor" */ return NULL; /* trying to read past ":endwhile"/":endfor" */
/* First time inside the ":while"/":for": get line normally. */ // First time inside the ":while"/":for": get line normally.
if (cp->getline == NULL) if (cp->getline == NULL) {
line = getcmdline(c, 0L, indent); line = getcmdline(c, 0L, indent, do_concat);
else } else {
line = cp->getline(c, cp->cookie, indent); line = cp->getline(c, cp->cookie, indent, do_concat);
}
if (line != NULL) { if (line != NULL) {
store_loop_line(cp->lines_gap, line); store_loop_line(cp->lines_gap, line);
++cp->current_line; ++cp->current_line;

View File

@ -1991,7 +1991,8 @@ char_u *
getcmdline ( getcmdline (
int firstc, int firstc,
long count, // only used for incremental search long count, // only used for incremental search
int indent // indent for inside conditionals int indent, // indent for inside conditionals
bool do_concat // unused
) )
{ {
// Be prepared for situations where cmdline can be invoked recursively. // Be prepared for situations where cmdline can be invoked recursively.
@ -2167,17 +2168,18 @@ static void correct_screencol(int idx, int cells, int *col)
* Get an Ex command line for the ":" command. * Get an Ex command line for the ":" command.
*/ */
char_u * char_u *
getexline ( getexline(
int c, /* normally ':', NUL for ":append" */ int c, // normally ':', NUL for ":append"
void *cookie, void *cookie,
int indent /* indent for inside conditionals */ int indent, // indent for inside conditionals
bool do_concat
) )
{ {
/* When executing a register, remove ':' that's in front of each line. */ /* When executing a register, remove ':' that's in front of each line. */
if (exec_from_reg && vpeekc() == ':') if (exec_from_reg && vpeekc() == ':')
(void)vgetc(); (void)vgetc();
return getcmdline(c, 1L, indent); return getcmdline(c, 1L, indent, do_concat);
} }
/* /*
@ -2187,11 +2189,12 @@ getexline (
* Returns a string in allocated memory or NULL. * Returns a string in allocated memory or NULL.
*/ */
char_u * char_u *
getexmodeline ( getexmodeline(
int promptc, /* normally ':', NUL for ":append" and '?' for int promptc, // normally ':', NUL for ":append" and '?'
:s prompt */ // for :s prompt
void *cookie, void *cookie,
int indent /* indent for inside conditionals */ int indent, // indent for inside conditionals
bool do_concat
) )
{ {
garray_T line_ga; garray_T line_ga;
@ -6308,7 +6311,7 @@ char *script_get(exarg_T *const eap, size_t *const lenp)
for (;;) { for (;;) {
char *const theline = (char *)eap->getline( char *const theline = (char *)eap->getline(
eap->cstack->cs_looplevel > 0 ? -1 : eap->cstack->cs_looplevel > 0 ? -1 :
NUL, eap->cookie, 0); NUL, eap->cookie, 0, true);
if (theline == NULL || strcmp(end_pattern, theline) == 0) { if (theline == NULL || strcmp(end_pattern, theline) == 0) {
xfree(theline); xfree(theline);

View File

@ -7100,12 +7100,10 @@ auto_next_pat(
} }
} }
/* /// Get next autocommand command.
* Get next autocommand command. /// Called by do_cmdline() to get the next line for ":if".
* Called by do_cmdline() to get the next line for ":if". /// @return allocated string, or NULL for end of autocommands.
* Returns allocated string, or NULL for end of autocommands. char_u *getnextac(int c, void *cookie, int indent, bool do_concat)
*/
char_u *getnextac(int c, void *cookie, int indent)
{ {
AutoPatCmd *acp = (AutoPatCmd *)cookie; AutoPatCmd *acp = (AutoPatCmd *)cookie;
char_u *retval; char_u *retval;

View File

@ -4419,7 +4419,7 @@ mapblock_T *get_maphash(int index, buf_T *buf)
} }
/// Get command argument for <Cmd> key /// Get command argument for <Cmd> key
char_u * getcmdkeycmd(int promptc, void *cookie, int indent) char_u * getcmdkeycmd(int promptc, void *cookie, int indent, bool do_concat)
{ {
garray_T line_ga; garray_T line_ga;
int c1 = -1, c2; int c1 = -1, c2;

View File

@ -5343,7 +5343,7 @@ static void nv_search(cmdarg_T *cap)
// When using 'incsearch' the cursor may be moved to set a different search // When using 'incsearch' the cursor may be moved to set a different search
// start position. // start position.
cap->searchbuf = getcmdline(cap->cmdchar, cap->count1, 0); cap->searchbuf = getcmdline(cap->cmdchar, cap->count1, 0, true);
if (cap->searchbuf == NULL) { if (cap->searchbuf == NULL) {
clearop(oap); clearop(oap);

View File

@ -671,13 +671,15 @@ int get_expr_register(void)
{ {
char_u *new_line; char_u *new_line;
new_line = getcmdline('=', 0L, 0); new_line = getcmdline('=', 0L, 0, true);
if (new_line == NULL) if (new_line == NULL) {
return NUL; return NUL;
if (*new_line == NUL) /* use previous line */ }
if (*new_line == NUL) { // use previous line
xfree(new_line); xfree(new_line);
else } else {
set_expr_line(new_line); set_expr_line(new_line);
}
return '='; return '=';
} }