mirror of
https://github.com/zoriya/vim.git
synced 2025-12-20 14:15:18 +00:00
patch 8.2.1049: Vim9: leaking memory when using continuation line
Problem: Vim9: leaking memory when using continuation line.
Solution: Keep a pointer to the continuation line in evalarg_T. Centralize
checking for a next command.
This commit is contained in:
@@ -285,7 +285,7 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
|
||||
++textwinlock;
|
||||
|
||||
vim_free(result);
|
||||
result = eval_to_string(bexpr, NULL, TRUE);
|
||||
result = eval_to_string(bexpr, TRUE);
|
||||
|
||||
// Remove one trailing newline, it is added when the result was a
|
||||
// list and it's hardly ever useful. If the user really wants a
|
||||
|
||||
@@ -4094,7 +4094,7 @@ build_stl_str_hl(
|
||||
tv.vval.v_number = wp->w_id;
|
||||
set_var((char_u *)"g:statusline_winid", &tv, FALSE);
|
||||
|
||||
usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox);
|
||||
usefmt = eval_to_string_safe(fmt + 2, use_sandbox);
|
||||
if (usefmt == NULL)
|
||||
usefmt = fmt;
|
||||
|
||||
@@ -4434,7 +4434,7 @@ build_stl_str_hl(
|
||||
if (curwin != save_curwin)
|
||||
VIsual_active = FALSE;
|
||||
|
||||
str = eval_to_string_safe(p, &t, use_sandbox);
|
||||
str = eval_to_string_safe(p, use_sandbox);
|
||||
|
||||
curwin = save_curwin;
|
||||
curbuf = save_curbuf;
|
||||
|
||||
@@ -86,7 +86,7 @@ eval_client_expr_to_string(char_u *expr)
|
||||
// to be typed. Do generate errors so that try/catch works.
|
||||
++emsg_silent;
|
||||
|
||||
res = eval_to_string(expr, NULL, TRUE);
|
||||
res = eval_to_string(expr, TRUE);
|
||||
|
||||
debug_break_level = save_dbl;
|
||||
redir_off = save_ro;
|
||||
|
||||
70
src/eval.c
70
src/eval.c
@@ -161,7 +161,7 @@ eval_clear(void)
|
||||
eval_to_bool(
|
||||
char_u *arg,
|
||||
int *error,
|
||||
char_u **nextcmd,
|
||||
exarg_T *eap,
|
||||
int skip) // only parse, don't execute
|
||||
{
|
||||
typval_T tv;
|
||||
@@ -169,7 +169,7 @@ eval_to_bool(
|
||||
|
||||
if (skip)
|
||||
++emsg_skip;
|
||||
if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE) == FAIL)
|
||||
if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE) == FAIL)
|
||||
*error = TRUE;
|
||||
else
|
||||
{
|
||||
@@ -317,7 +317,7 @@ eval_expr_to_bool(typval_T *expr, int *error)
|
||||
char_u *
|
||||
eval_to_string_skip(
|
||||
char_u *arg,
|
||||
char_u **nextcmd,
|
||||
exarg_T *eap,
|
||||
int skip) // only parse, don't execute
|
||||
{
|
||||
typval_T tv;
|
||||
@@ -325,7 +325,7 @@ eval_to_string_skip(
|
||||
|
||||
if (skip)
|
||||
++emsg_skip;
|
||||
if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE)
|
||||
if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE)
|
||||
== FAIL || skip)
|
||||
retval = NULL;
|
||||
else
|
||||
@@ -361,7 +361,6 @@ skip_expr(char_u **pp)
|
||||
char_u *
|
||||
eval_to_string(
|
||||
char_u *arg,
|
||||
char_u **nextcmd,
|
||||
int convert)
|
||||
{
|
||||
typval_T tv;
|
||||
@@ -371,7 +370,7 @@ eval_to_string(
|
||||
char_u numbuf[NUMBUFLEN];
|
||||
#endif
|
||||
|
||||
if (eval0(arg, &tv, nextcmd, &EVALARG_EVALUATE) == FAIL)
|
||||
if (eval0(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL)
|
||||
retval = NULL;
|
||||
else
|
||||
{
|
||||
@@ -409,7 +408,6 @@ eval_to_string(
|
||||
char_u *
|
||||
eval_to_string_safe(
|
||||
char_u *arg,
|
||||
char_u **nextcmd,
|
||||
int use_sandbox)
|
||||
{
|
||||
char_u *retval;
|
||||
@@ -419,7 +417,7 @@ eval_to_string_safe(
|
||||
if (use_sandbox)
|
||||
++sandbox;
|
||||
++textwinlock;
|
||||
retval = eval_to_string(arg, nextcmd, FALSE);
|
||||
retval = eval_to_string(arg, FALSE);
|
||||
if (use_sandbox)
|
||||
--sandbox;
|
||||
--textwinlock;
|
||||
@@ -459,12 +457,12 @@ eval_to_number(char_u *expr)
|
||||
* Returns NULL when there is an error.
|
||||
*/
|
||||
typval_T *
|
||||
eval_expr(char_u *arg, char_u **nextcmd)
|
||||
eval_expr(char_u *arg, exarg_T *eap)
|
||||
{
|
||||
typval_T *tv;
|
||||
|
||||
tv = ALLOC_ONE(typval_T);
|
||||
if (tv != NULL && eval0(arg, tv, nextcmd, &EVALARG_EVALUATE) == FAIL)
|
||||
if (tv != NULL && eval0(arg, tv, eap, &EVALARG_EVALUATE) == FAIL)
|
||||
VIM_CLEAR(tv);
|
||||
|
||||
return tv;
|
||||
@@ -1418,7 +1416,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
|
||||
eval_for_line(
|
||||
char_u *arg,
|
||||
int *errp,
|
||||
char_u **nextcmdp,
|
||||
exarg_T *eap,
|
||||
int skip)
|
||||
{
|
||||
forinfo_T *fi;
|
||||
@@ -1448,7 +1446,7 @@ eval_for_line(
|
||||
|
||||
if (skip)
|
||||
++emsg_skip;
|
||||
if (eval0(skipwhite(expr + 2), &tv, nextcmdp, &evalarg) == OK)
|
||||
if (eval0(skipwhite(expr + 2), &tv, eap, &evalarg) == OK)
|
||||
{
|
||||
*errp = FALSE;
|
||||
if (!skip)
|
||||
@@ -1795,6 +1793,17 @@ eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
|
||||
return arg;
|
||||
}
|
||||
|
||||
/*
|
||||
* To be called when eval_next_non_blank() sets "getnext" to TRUE.
|
||||
*/
|
||||
static char_u *
|
||||
eval_next_line(evalarg_T *evalarg)
|
||||
{
|
||||
vim_free(evalarg->eval_tofree);
|
||||
evalarg->eval_tofree = getsourceline(0, evalarg->eval_cookie, 0, TRUE);
|
||||
return skipwhite(evalarg->eval_tofree);
|
||||
}
|
||||
|
||||
/*
|
||||
* The "evaluate" argument: When FALSE, the argument is only parsed but not
|
||||
* executed. The function may return OK, but the rettv will be of type
|
||||
@@ -1813,7 +1822,7 @@ eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
|
||||
eval0(
|
||||
char_u *arg,
|
||||
typval_T *rettv,
|
||||
char_u **nextcmd,
|
||||
exarg_T *eap,
|
||||
evalarg_T *evalarg)
|
||||
{
|
||||
int ret;
|
||||
@@ -1822,8 +1831,11 @@ eval0(
|
||||
int called_emsg_before = called_emsg;
|
||||
int flags = evalarg == NULL ? 0 : evalarg->eval_flags;
|
||||
|
||||
if (evalarg != NULL)
|
||||
evalarg->eval_tofree = NULL;
|
||||
p = skipwhite(arg);
|
||||
ret = eval1(&p, rettv, evalarg);
|
||||
|
||||
if (ret == FAIL || !ends_excmd2(arg, p))
|
||||
{
|
||||
if (ret != FAIL)
|
||||
@@ -1841,8 +1853,27 @@ eval0(
|
||||
semsg(_(e_invexpr2), arg);
|
||||
ret = FAIL;
|
||||
}
|
||||
if (nextcmd != NULL)
|
||||
*nextcmd = check_nextcmd(p);
|
||||
|
||||
if (eap != NULL)
|
||||
eap->nextcmd = check_nextcmd(p);
|
||||
|
||||
if (evalarg != NULL)
|
||||
{
|
||||
if (eap != NULL)
|
||||
{
|
||||
if (evalarg->eval_tofree != NULL)
|
||||
{
|
||||
// We may need to keep the original command line, e.g. for
|
||||
// ":let" it has the variable names. But we may also need the
|
||||
// new one, "nextcmd" points into it. Keep both.
|
||||
vim_free(eap->cmdline_tofree);
|
||||
eap->cmdline_tofree = *eap->cmdlinep;
|
||||
*eap->cmdlinep = evalarg->eval_tofree;
|
||||
}
|
||||
}
|
||||
else
|
||||
vim_free(evalarg->eval_tofree);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -2305,7 +2336,7 @@ eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
|
||||
if (op != '+' && op != '-' && !concat)
|
||||
break;
|
||||
if (getnext)
|
||||
*arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE));
|
||||
*arg = eval_next_line(evalarg);
|
||||
|
||||
if ((op != '+' || (rettv->v_type != VAR_LIST
|
||||
&& rettv->v_type != VAR_BLOB))
|
||||
@@ -2497,7 +2528,7 @@ eval6(
|
||||
if (op != '*' && op != '/' && op != '%')
|
||||
break;
|
||||
if (getnext)
|
||||
*arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE));
|
||||
*arg = eval_next_line(evalarg);
|
||||
|
||||
if (evaluate)
|
||||
{
|
||||
@@ -4734,7 +4765,6 @@ make_expanded_name(
|
||||
char_u c1;
|
||||
char_u *retval = NULL;
|
||||
char_u *temp_result;
|
||||
char_u *nextcmd = NULL;
|
||||
|
||||
if (expr_end == NULL || in_end == NULL)
|
||||
return NULL;
|
||||
@@ -4743,8 +4773,8 @@ make_expanded_name(
|
||||
c1 = *in_end;
|
||||
*in_end = NUL;
|
||||
|
||||
temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE);
|
||||
if (temp_result != NULL && nextcmd == NULL)
|
||||
temp_result = eval_to_string(expr_start + 1, FALSE);
|
||||
if (temp_result != NULL)
|
||||
{
|
||||
retval = alloc(STRLEN(temp_result) + (expr_start - in_start)
|
||||
+ (in_end - expr_end) + 1);
|
||||
|
||||
@@ -800,7 +800,7 @@ ex_let(exarg_T *eap)
|
||||
evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
|
||||
evalarg.eval_cookie = eap->getline == getsourceline
|
||||
? eap->cookie : NULL;
|
||||
i = eval0(expr, &rettv, &eap->nextcmd, &evalarg);
|
||||
i = eval0(expr, &rettv, eap, &evalarg);
|
||||
if (eap->skip)
|
||||
--emsg_skip;
|
||||
}
|
||||
|
||||
@@ -2609,6 +2609,7 @@ doend:
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
--ex_nesting_level;
|
||||
vim_free(ea.cmdline_tofree);
|
||||
#endif
|
||||
|
||||
return ea.nextcmd;
|
||||
@@ -4912,7 +4913,7 @@ ex_colorscheme(exarg_T *eap)
|
||||
if (expr != NULL)
|
||||
{
|
||||
++emsg_off;
|
||||
p = eval_to_string(expr, NULL, FALSE);
|
||||
p = eval_to_string(expr, FALSE);
|
||||
--emsg_off;
|
||||
vim_free(expr);
|
||||
}
|
||||
|
||||
@@ -900,7 +900,7 @@ ex_eval(exarg_T *eap)
|
||||
evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
|
||||
evalarg.eval_cookie = eap->getline == getsourceline ? eap->cookie : NULL;
|
||||
|
||||
if (eval0(eap->arg, &tv, &eap->nextcmd, &evalarg) == OK)
|
||||
if (eval0(eap->arg, &tv, eap, &evalarg) == OK)
|
||||
clear_tv(&tv);
|
||||
}
|
||||
|
||||
@@ -929,7 +929,7 @@ ex_if(exarg_T *eap)
|
||||
skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
|
||||
&& !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
|
||||
|
||||
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
|
||||
result = eval_to_bool(eap->arg, &error, eap, skip);
|
||||
|
||||
if (!skip && !error)
|
||||
{
|
||||
@@ -1041,7 +1041,7 @@ ex_else(exarg_T *eap)
|
||||
|
||||
if (eap->cmdidx == CMD_elseif)
|
||||
{
|
||||
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
|
||||
result = eval_to_bool(eap->arg, &error, eap, skip);
|
||||
|
||||
// When throwing error exceptions, we want to throw always the first
|
||||
// of several errors in a row. This is what actually happens when
|
||||
@@ -1103,7 +1103,7 @@ ex_while(exarg_T *eap)
|
||||
/*
|
||||
* ":while bool-expr"
|
||||
*/
|
||||
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
|
||||
result = eval_to_bool(eap->arg, &error, eap, skip);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1122,7 +1122,7 @@ ex_while(exarg_T *eap)
|
||||
else
|
||||
{
|
||||
// Evaluate the argument and get the info in a structure.
|
||||
fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip);
|
||||
fi = eval_for_line(eap->arg, &error, eap, skip);
|
||||
cstack->cs_forinfo[cstack->cs_idx] = fi;
|
||||
}
|
||||
|
||||
@@ -1322,7 +1322,7 @@ ex_throw(exarg_T *eap)
|
||||
char_u *value;
|
||||
|
||||
if (*arg != NUL && *arg != '|' && *arg != '\n')
|
||||
value = eval_to_string_skip(arg, &eap->nextcmd, eap->skip);
|
||||
value = eval_to_string_skip(arg, eap, eap->skip);
|
||||
else
|
||||
{
|
||||
emsg(_(e_argreq));
|
||||
|
||||
@@ -3083,7 +3083,7 @@ expand_backtick(
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
if (*cmd == '=') // `={expr}`: Expand expression
|
||||
buffer = eval_to_string(cmd + 1, &p, TRUE);
|
||||
buffer = eval_to_string(cmd + 1, TRUE);
|
||||
else
|
||||
#endif
|
||||
buffer = get_cmd_output(cmd, NULL,
|
||||
|
||||
@@ -2079,7 +2079,7 @@ eval_includeexpr(char_u *ptr, int len)
|
||||
char_u *res;
|
||||
|
||||
set_vim_var_string(VV_FNAME, ptr, len);
|
||||
res = eval_to_string_safe(curbuf->b_p_inex, NULL,
|
||||
res = eval_to_string_safe(curbuf->b_p_inex,
|
||||
was_set_insecurely((char_u *)"includeexpr", OPT_LOCAL));
|
||||
set_vim_var_string(VV_FNAME, NULL, 0);
|
||||
return res;
|
||||
|
||||
@@ -1928,7 +1928,7 @@ get_foldtext(
|
||||
curbuf = wp->w_buffer;
|
||||
|
||||
++emsg_silent; // handle exceptions, but don't display errors
|
||||
text = eval_to_string_safe(wp->w_p_fdt, NULL,
|
||||
text = eval_to_string_safe(wp->w_p_fdt,
|
||||
was_set_insecurely((char_u *)"foldtext", OPT_LOCAL));
|
||||
--emsg_silent;
|
||||
|
||||
|
||||
@@ -1882,7 +1882,7 @@ EXTERN char windowsVersion[20] INIT(= {0});
|
||||
EXTERN listitem_T range_list_item;
|
||||
|
||||
// Passed to an eval() function to enable evaluation.
|
||||
EXTERN evalarg_T EVALARG_EVALUATE INIT2(EVAL_EVALUATE, NULL);
|
||||
EXTERN evalarg_T EVALARG_EVALUATE INIT3(EVAL_EVALUATE, NULL, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef MSWIN
|
||||
|
||||
@@ -388,7 +388,7 @@ CVim::Eval(BSTR expr, BSTR *result)
|
||||
|
||||
/* Evaluate the expression */
|
||||
++emsg_skip;
|
||||
str = (char *)eval_to_string((char_u *)buffer, NULL, TRUE);
|
||||
str = (char *)eval_to_string((char_u *)buffer, TRUE);
|
||||
--emsg_skip;
|
||||
vim_free(buffer);
|
||||
if (str == NULL)
|
||||
|
||||
@@ -832,7 +832,6 @@ msg_split(
|
||||
char_u *
|
||||
eval_to_string(
|
||||
char_u *arg UNUSED,
|
||||
char_u **nextcmd UNUSED,
|
||||
int dolist UNUSED)
|
||||
{
|
||||
return NULL;
|
||||
@@ -1562,7 +1561,7 @@ Eval(str)
|
||||
PREINIT:
|
||||
char_u *value;
|
||||
PPCODE:
|
||||
value = eval_to_string((char_u *)str, (char_u **)0, TRUE);
|
||||
value = eval_to_string((char_u *)str, TRUE);
|
||||
if (value == NULL)
|
||||
{
|
||||
XPUSHs(sv_2mortal(newSViv(0)));
|
||||
|
||||
@@ -1373,7 +1373,7 @@ tclvimexpr(
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
expr = Tcl_GetStringFromObj(objv[objn], NULL);
|
||||
str = (char *)eval_to_string((char_u *)expr, NULL, TRUE);
|
||||
str = (char *)eval_to_string((char_u *)expr, TRUE);
|
||||
if (str == NULL)
|
||||
Tcl_SetResult(interp, _("invalid expression"), TCL_STATIC);
|
||||
else
|
||||
|
||||
@@ -1614,7 +1614,7 @@ eval_map_expr(
|
||||
save_cursor = curwin->w_cursor;
|
||||
save_msg_col = msg_col;
|
||||
save_msg_row = msg_row;
|
||||
p = eval_to_string(expr, NULL, FALSE);
|
||||
p = eval_to_string(expr, FALSE);
|
||||
--textwinlock;
|
||||
--ex_normal_lock;
|
||||
curwin->w_cursor = save_cursor;
|
||||
|
||||
@@ -3,16 +3,16 @@ varnumber_T num_divide(varnumber_T n1, varnumber_T n2);
|
||||
varnumber_T num_modulus(varnumber_T n1, varnumber_T n2);
|
||||
void eval_init(void);
|
||||
void eval_clear(void);
|
||||
int eval_to_bool(char_u *arg, int *error, char_u **nextcmd, int skip);
|
||||
int eval_to_bool(char_u *arg, int *error, exarg_T *eap, int skip);
|
||||
int eval_expr_valid_arg(typval_T *tv);
|
||||
int eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv);
|
||||
int eval_expr_to_bool(typval_T *expr, int *error);
|
||||
char_u *eval_to_string_skip(char_u *arg, char_u **nextcmd, int skip);
|
||||
char_u *eval_to_string_skip(char_u *arg, exarg_T *eap, int skip);
|
||||
int skip_expr(char_u **pp);
|
||||
char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert);
|
||||
char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox);
|
||||
char_u *eval_to_string(char_u *arg, int convert);
|
||||
char_u *eval_to_string_safe(char_u *arg, int use_sandbox);
|
||||
varnumber_T eval_to_number(char_u *expr);
|
||||
typval_T *eval_expr(char_u *arg, char_u **nextcmd);
|
||||
typval_T *eval_expr(char_u *arg, exarg_T *eap);
|
||||
int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv);
|
||||
varnumber_T call_func_retnr(char_u *func, int argc, typval_T *argv);
|
||||
void *call_func_retstr(char_u *func, int argc, typval_T *argv);
|
||||
@@ -21,13 +21,13 @@ int eval_foldexpr(char_u *arg, int *cp);
|
||||
char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags);
|
||||
void clear_lval(lval_T *lp);
|
||||
void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, int flags, char_u *op);
|
||||
void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip);
|
||||
void *eval_for_line(char_u *arg, int *errp, exarg_T *eap, int skip);
|
||||
int next_for_item(void *fi_void, char_u *arg);
|
||||
void free_for_info(void *fi_void);
|
||||
void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx);
|
||||
int pattern_match(char_u *pat, char_u *text, int ic);
|
||||
int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, evalarg_T *evalarg);
|
||||
int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg_in);
|
||||
int eval0(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg);
|
||||
int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
||||
void eval_addblob(typval_T *tv1, typval_T *tv2);
|
||||
int eval_addlist(typval_T *tv1, typval_T *tv2);
|
||||
char_u *partial_name(partial_T *pt);
|
||||
|
||||
@@ -7680,7 +7680,7 @@ ex_cexpr(exarg_T *eap)
|
||||
|
||||
// Evaluate the expression. When the result is a string or a list we can
|
||||
// use it to fill the errorlist.
|
||||
tv = eval_expr(eap->arg, &eap->nextcmd);
|
||||
tv = eval_expr(eap->arg, eap);
|
||||
if (tv != NULL)
|
||||
{
|
||||
if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL)
|
||||
|
||||
@@ -2066,7 +2066,7 @@ vim_regsub_both(
|
||||
clear_tv(&rettv);
|
||||
}
|
||||
else
|
||||
eval_result = eval_to_string(source + 2, NULL, TRUE);
|
||||
eval_result = eval_to_string(source + 2, TRUE);
|
||||
|
||||
if (eval_result != NULL)
|
||||
{
|
||||
|
||||
@@ -136,7 +136,7 @@ get_expr_line(void)
|
||||
return expr_copy;
|
||||
|
||||
++nested;
|
||||
rv = eval_to_string(expr_copy, NULL, TRUE);
|
||||
rv = eval_to_string(expr_copy, TRUE);
|
||||
--nested;
|
||||
vim_free(expr_copy);
|
||||
return rv;
|
||||
|
||||
@@ -1148,7 +1148,7 @@ get_keymap_str(
|
||||
curwin = wp;
|
||||
STRCPY(buf, "b:keymap_name"); // must be writable
|
||||
++emsg_skip;
|
||||
s = p = eval_to_string(buf, NULL, FALSE);
|
||||
s = p = eval_to_string(buf, FALSE);
|
||||
--emsg_skip;
|
||||
curbuf = old_curbuf;
|
||||
curwin = old_curwin;
|
||||
|
||||
@@ -1753,6 +1753,9 @@ typedef struct {
|
||||
|
||||
// copied from exarg_T when "getline" is "getsourceline". Can be NULL.
|
||||
void *eval_cookie; // argument for getline()
|
||||
|
||||
// pointer to the line obtained with getsourceline()
|
||||
char_u *eval_tofree;
|
||||
} evalarg_T;
|
||||
|
||||
// Flags for expression evaluation.
|
||||
|
||||
@@ -3716,7 +3716,7 @@ ex_return(exarg_T *eap)
|
||||
|
||||
eap->nextcmd = NULL;
|
||||
if ((*arg != NUL && *arg != '|' && *arg != '\n')
|
||||
&& eval0(arg, &rettv, &eap->nextcmd, &evalarg) != FAIL)
|
||||
&& eval0(arg, &rettv, eap, &evalarg) != FAIL)
|
||||
{
|
||||
if (!eap->skip)
|
||||
returning = do_return(eap, FALSE, TRUE, &rettv);
|
||||
@@ -3773,7 +3773,7 @@ ex_call(exarg_T *eap)
|
||||
// instead to skip to any following command, e.g. for:
|
||||
// :if 0 | call dict.foo().bar() | endif
|
||||
++emsg_skip;
|
||||
if (eval0(eap->arg, &rettv, &eap->nextcmd, NULL) != FAIL)
|
||||
if (eval0(eap->arg, &rettv, eap, NULL) != FAIL)
|
||||
clear_tv(&rettv);
|
||||
--emsg_skip;
|
||||
return;
|
||||
|
||||
@@ -754,6 +754,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1049,
|
||||
/**/
|
||||
1048,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user