To: vim_dev@googlegroups.com Subject: Patch 8.2.1049 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1049 (after 8.2.1047) 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. Files: src/structs.h, src/eval.c, src/proto/eval.pro, src/beval.c, src/buffer.c, src/clientserver.c, src/evalvars.c, src/ex_docmd.c, src/ex_eval.c, src/filepath.c, src/findfile.c, src/fold.c, src/globals.h, src/if_ole.cpp, src/if_perl.xs, src/if_tcl.c, src/map.c, src/quickfix.c, src/regexp.c, src/register.c, src/screen.c, src/userfunc.c *** ../vim-8.2.1048/src/structs.h 2020-06-24 19:05:23.899362149 +0200 --- src/structs.h 2020-06-24 19:17:05.732525781 +0200 *************** *** 1753,1758 **** --- 1753,1761 ---- // 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. *** ../vim-8.2.1048/src/eval.c 2020-06-24 18:37:28.355249390 +0200 --- src/eval.c 2020-06-24 20:28:54.602106733 +0200 *************** *** 161,167 **** eval_to_bool( char_u *arg, int *error, ! char_u **nextcmd, int skip) // only parse, don't execute { typval_T tv; --- 161,167 ---- eval_to_bool( char_u *arg, int *error, ! exarg_T *eap, int skip) // only parse, don't execute { typval_T tv; *************** *** 169,175 **** if (skip) ++emsg_skip; ! if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE) == FAIL) *error = TRUE; else { --- 169,175 ---- if (skip) ++emsg_skip; ! if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE) == FAIL) *error = TRUE; else { *************** *** 317,323 **** char_u * eval_to_string_skip( char_u *arg, ! char_u **nextcmd, int skip) // only parse, don't execute { typval_T tv; --- 317,323 ---- char_u * eval_to_string_skip( char_u *arg, ! exarg_T *eap, int skip) // only parse, don't execute { typval_T tv; *************** *** 325,331 **** if (skip) ++emsg_skip; ! if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE) == FAIL || skip) retval = NULL; else --- 325,331 ---- if (skip) ++emsg_skip; ! if (eval0(arg, &tv, eap, skip ? NULL : &EVALARG_EVALUATE) == FAIL || skip) retval = NULL; else *************** *** 361,367 **** char_u * eval_to_string( char_u *arg, - char_u **nextcmd, int convert) { typval_T tv; --- 361,366 ---- *************** *** 371,377 **** char_u numbuf[NUMBUFLEN]; #endif ! if (eval0(arg, &tv, nextcmd, &EVALARG_EVALUATE) == FAIL) retval = NULL; else { --- 370,376 ---- char_u numbuf[NUMBUFLEN]; #endif ! if (eval0(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL) retval = NULL; else { *************** *** 409,415 **** char_u * eval_to_string_safe( char_u *arg, - char_u **nextcmd, int use_sandbox) { char_u *retval; --- 408,413 ---- *************** *** 419,425 **** if (use_sandbox) ++sandbox; ++textwinlock; ! retval = eval_to_string(arg, nextcmd, FALSE); if (use_sandbox) --sandbox; --textwinlock; --- 417,423 ---- if (use_sandbox) ++sandbox; ++textwinlock; ! retval = eval_to_string(arg, FALSE); if (use_sandbox) --sandbox; --textwinlock; *************** *** 459,470 **** * Returns NULL when there is an error. */ typval_T * ! eval_expr(char_u *arg, char_u **nextcmd) { typval_T *tv; tv = ALLOC_ONE(typval_T); ! if (tv != NULL && eval0(arg, tv, nextcmd, &EVALARG_EVALUATE) == FAIL) VIM_CLEAR(tv); return tv; --- 457,468 ---- * Returns NULL when there is an error. */ typval_T * ! eval_expr(char_u *arg, exarg_T *eap) { typval_T *tv; tv = ALLOC_ONE(typval_T); ! if (tv != NULL && eval0(arg, tv, eap, &EVALARG_EVALUATE) == FAIL) VIM_CLEAR(tv); return tv; *************** *** 1418,1424 **** eval_for_line( char_u *arg, int *errp, ! char_u **nextcmdp, int skip) { forinfo_T *fi; --- 1416,1422 ---- eval_for_line( char_u *arg, int *errp, ! exarg_T *eap, int skip) { forinfo_T *fi; *************** *** 1448,1454 **** if (skip) ++emsg_skip; ! if (eval0(skipwhite(expr + 2), &tv, nextcmdp, &evalarg) == OK) { *errp = FALSE; if (!skip) --- 1446,1452 ---- if (skip) ++emsg_skip; ! if (eval0(skipwhite(expr + 2), &tv, eap, &evalarg) == OK) { *errp = FALSE; if (!skip) *************** *** 1796,1801 **** --- 1794,1810 ---- } /* + * 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 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. *************** *** 1813,1819 **** eval0( char_u *arg, typval_T *rettv, ! char_u **nextcmd, evalarg_T *evalarg) { int ret; --- 1822,1828 ---- eval0( char_u *arg, typval_T *rettv, ! exarg_T *eap, evalarg_T *evalarg) { int ret; *************** *** 1822,1829 **** --- 1831,1841 ---- 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,1848 **** semsg(_(e_invexpr2), arg); ret = FAIL; } ! if (nextcmd != NULL) ! *nextcmd = check_nextcmd(p); return ret; } --- 1853,1879 ---- semsg(_(e_invexpr2), arg); ret = FAIL; } ! ! 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,2311 **** if (op != '+' && op != '-' && !concat) break; if (getnext) ! *arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE)); if ((op != '+' || (rettv->v_type != VAR_LIST && rettv->v_type != VAR_BLOB)) --- 2336,2342 ---- if (op != '+' && op != '-' && !concat) break; if (getnext) ! *arg = eval_next_line(evalarg); if ((op != '+' || (rettv->v_type != VAR_LIST && rettv->v_type != VAR_BLOB)) *************** *** 2497,2503 **** if (op != '*' && op != '/' && op != '%') break; if (getnext) ! *arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE)); if (evaluate) { --- 2528,2534 ---- if (op != '*' && op != '/' && op != '%') break; if (getnext) ! *arg = eval_next_line(evalarg); if (evaluate) { *************** *** 4734,4740 **** char_u c1; char_u *retval = NULL; char_u *temp_result; - char_u *nextcmd = NULL; if (expr_end == NULL || in_end == NULL) return NULL; --- 4765,4770 ---- *************** *** 4743,4750 **** c1 = *in_end; *in_end = NUL; ! temp_result = eval_to_string(expr_start + 1, &nextcmd, FALSE); ! if (temp_result != NULL && nextcmd == NULL) { retval = alloc(STRLEN(temp_result) + (expr_start - in_start) + (in_end - expr_end) + 1); --- 4773,4780 ---- c1 = *in_end; *in_end = NUL; ! 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); *** ../vim-8.2.1048/src/proto/eval.pro 2020-06-24 18:37:28.355249390 +0200 --- src/proto/eval.pro 2020-06-24 19:54:54.631983422 +0200 *************** *** 3,18 **** 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_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); 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); varnumber_T eval_to_number(char_u *expr); ! typval_T *eval_expr(char_u *arg, char_u **nextcmd); 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); --- 3,18 ---- 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, 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, exarg_T *eap, int skip); int skip_expr(char_u **pp); ! 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, 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,33 **** 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); 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); 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); --- 21,33 ---- 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, 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, 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); *** ../vim-8.2.1048/src/beval.c 2020-04-30 22:29:36.622024155 +0200 --- src/beval.c 2020-06-24 19:44:08.266365079 +0200 *************** *** 285,291 **** ++textwinlock; vim_free(result); ! result = eval_to_string(bexpr, NULL, 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 --- 285,291 ---- ++textwinlock; vim_free(result); ! 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 *** ../vim-8.2.1048/src/buffer.c 2020-06-12 22:30:57.629228449 +0200 --- src/buffer.c 2020-06-24 19:35:23.508322897 +0200 *************** *** 4094,4100 **** 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); if (usefmt == NULL) usefmt = fmt; --- 4094,4100 ---- tv.vval.v_number = wp->w_id; set_var((char_u *)"g:statusline_winid", &tv, FALSE); ! usefmt = eval_to_string_safe(fmt + 2, use_sandbox); if (usefmt == NULL) usefmt = fmt; *************** *** 4434,4440 **** if (curwin != save_curwin) VIsual_active = FALSE; ! str = eval_to_string_safe(p, &t, use_sandbox); curwin = save_curwin; curbuf = save_curbuf; --- 4434,4440 ---- if (curwin != save_curwin) VIsual_active = FALSE; ! str = eval_to_string_safe(p, use_sandbox); curwin = save_curwin; curbuf = save_curbuf; *** ../vim-8.2.1048/src/clientserver.c 2020-04-26 14:29:53.450969744 +0200 --- src/clientserver.c 2020-06-24 19:44:20.858318413 +0200 *************** *** 86,92 **** // to be typed. Do generate errors so that try/catch works. ++emsg_silent; ! res = eval_to_string(expr, NULL, TRUE); debug_break_level = save_dbl; redir_off = save_ro; --- 86,92 ---- // to be typed. Do generate errors so that try/catch works. ++emsg_silent; ! res = eval_to_string(expr, TRUE); debug_break_level = save_dbl; redir_off = save_ro; *** ../vim-8.2.1048/src/evalvars.c 2020-06-24 18:37:28.359249374 +0200 --- src/evalvars.c 2020-06-24 20:03:26.734716651 +0200 *************** *** 800,806 **** evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE; evalarg.eval_cookie = eap->getline == getsourceline ? eap->cookie : NULL; ! i = eval0(expr, &rettv, &eap->nextcmd, &evalarg); if (eap->skip) --emsg_skip; } --- 800,806 ---- evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE; evalarg.eval_cookie = eap->getline == getsourceline ? eap->cookie : NULL; ! i = eval0(expr, &rettv, eap, &evalarg); if (eap->skip) --emsg_skip; } *** ../vim-8.2.1048/src/ex_docmd.c 2020-06-22 23:02:14.769942569 +0200 --- src/ex_docmd.c 2020-06-24 20:11:53.041377513 +0200 *************** *** 2609,2614 **** --- 2609,2615 ---- #ifdef FEAT_EVAL --ex_nesting_level; + vim_free(ea.cmdline_tofree); #endif return ea.nextcmd; *************** *** 4912,4918 **** if (expr != NULL) { ++emsg_off; ! p = eval_to_string(expr, NULL, FALSE); --emsg_off; vim_free(expr); } --- 4913,4919 ---- if (expr != NULL) { ++emsg_off; ! p = eval_to_string(expr, FALSE); --emsg_off; vim_free(expr); } *** ../vim-8.2.1048/src/ex_eval.c 2020-06-24 18:37:28.355249390 +0200 --- src/ex_eval.c 2020-06-24 20:03:43.542679069 +0200 *************** *** 900,906 **** 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) clear_tv(&tv); } --- 900,906 ---- evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE; evalarg.eval_cookie = eap->getline == getsourceline ? eap->cookie : NULL; ! if (eval0(eap->arg, &tv, eap, &evalarg) == OK) clear_tv(&tv); } *************** *** 929,935 **** 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); if (!skip && !error) { --- 929,935 ---- 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, skip); if (!skip && !error) { *************** *** 1041,1047 **** if (eap->cmdidx == CMD_elseif) { ! result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip); // When throwing error exceptions, we want to throw always the first // of several errors in a row. This is what actually happens when --- 1041,1047 ---- if (eap->cmdidx == CMD_elseif) { ! 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,1109 **** /* * ":while bool-expr" */ ! result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip); } else { --- 1103,1109 ---- /* * ":while bool-expr" */ ! result = eval_to_bool(eap->arg, &error, eap, skip); } else { *************** *** 1122,1128 **** else { // Evaluate the argument and get the info in a structure. ! fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip); cstack->cs_forinfo[cstack->cs_idx] = fi; } --- 1122,1128 ---- else { // Evaluate the argument and get the info in a structure. ! fi = eval_for_line(eap->arg, &error, eap, skip); cstack->cs_forinfo[cstack->cs_idx] = fi; } *************** *** 1322,1328 **** char_u *value; if (*arg != NUL && *arg != '|' && *arg != '\n') ! value = eval_to_string_skip(arg, &eap->nextcmd, eap->skip); else { emsg(_(e_argreq)); --- 1322,1328 ---- char_u *value; if (*arg != NUL && *arg != '|' && *arg != '\n') ! value = eval_to_string_skip(arg, eap, eap->skip); else { emsg(_(e_argreq)); *** ../vim-8.2.1048/src/filepath.c 2020-06-16 20:03:38.747351038 +0200 --- src/filepath.c 2020-06-24 19:46:01.045948216 +0200 *************** *** 3083,3089 **** #ifdef FEAT_EVAL if (*cmd == '=') // `={expr}`: Expand expression ! buffer = eval_to_string(cmd + 1, &p, TRUE); else #endif buffer = get_cmd_output(cmd, NULL, --- 3083,3089 ---- #ifdef FEAT_EVAL if (*cmd == '=') // `={expr}`: Expand expression ! buffer = eval_to_string(cmd + 1, TRUE); else #endif buffer = get_cmd_output(cmd, NULL, *** ../vim-8.2.1048/src/findfile.c 2020-06-15 21:41:51.791814391 +0200 --- src/findfile.c 2020-06-24 19:35:41.128256520 +0200 *************** *** 2079,2085 **** char_u *res; set_vim_var_string(VV_FNAME, ptr, len); ! res = eval_to_string_safe(curbuf->b_p_inex, NULL, was_set_insecurely((char_u *)"includeexpr", OPT_LOCAL)); set_vim_var_string(VV_FNAME, NULL, 0); return res; --- 2079,2085 ---- char_u *res; set_vim_var_string(VV_FNAME, ptr, len); ! 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; *** ../vim-8.2.1048/src/fold.c 2019-12-01 21:40:39.000000000 +0100 --- src/fold.c 2020-06-24 19:35:07.084384839 +0200 *************** *** 1928,1934 **** curbuf = wp->w_buffer; ++emsg_silent; // handle exceptions, but don't display errors ! text = eval_to_string_safe(wp->w_p_fdt, NULL, was_set_insecurely((char_u *)"foldtext", OPT_LOCAL)); --emsg_silent; --- 1928,1934 ---- curbuf = wp->w_buffer; ++emsg_silent; // handle exceptions, but don't display errors ! text = eval_to_string_safe(wp->w_p_fdt, was_set_insecurely((char_u *)"foldtext", OPT_LOCAL)); --emsg_silent; *** ../vim-8.2.1048/src/globals.h 2020-06-24 18:37:28.355249390 +0200 --- src/globals.h 2020-06-24 19:21:15.643587086 +0200 *************** *** 1882,1888 **** EXTERN listitem_T range_list_item; // Passed to an eval() function to enable evaluation. ! EXTERN evalarg_T EVALARG_EVALUATE INIT2(EVAL_EVALUATE, NULL); #endif #ifdef MSWIN --- 1882,1888 ---- EXTERN listitem_T range_list_item; // Passed to an eval() function to enable evaluation. ! EXTERN evalarg_T EVALARG_EVALUATE INIT3(EVAL_EVALUATE, NULL, NULL); #endif #ifdef MSWIN *** ../vim-8.2.1048/src/if_ole.cpp 2019-10-12 21:53:01.000000000 +0200 --- src/if_ole.cpp 2020-06-24 19:47:25.585636335 +0200 *************** *** 388,394 **** /* Evaluate the expression */ ++emsg_skip; ! str = (char *)eval_to_string((char_u *)buffer, NULL, TRUE); --emsg_skip; vim_free(buffer); if (str == NULL) --- 388,394 ---- /* Evaluate the expression */ ++emsg_skip; ! str = (char *)eval_to_string((char_u *)buffer, TRUE); --emsg_skip; vim_free(buffer); if (str == NULL) *** ../vim-8.2.1048/src/if_perl.xs 2020-06-21 20:06:50.970050457 +0200 --- src/if_perl.xs 2020-06-24 19:47:20.677654435 +0200 *************** *** 832,838 **** char_u * eval_to_string( char_u *arg UNUSED, - char_u **nextcmd UNUSED, int dolist UNUSED) { return NULL; --- 832,837 ---- *************** *** 1562,1568 **** PREINIT: char_u *value; PPCODE: ! value = eval_to_string((char_u *)str, (char_u **)0, TRUE); if (value == NULL) { XPUSHs(sv_2mortal(newSViv(0))); --- 1561,1567 ---- PREINIT: char_u *value; PPCODE: ! value = eval_to_string((char_u *)str, TRUE); if (value == NULL) { XPUSHs(sv_2mortal(newSViv(0))); *** ../vim-8.2.1048/src/if_tcl.c 2020-05-30 20:30:42.892816571 +0200 --- src/if_tcl.c 2020-06-24 19:46:09.793915941 +0200 *************** *** 1373,1379 **** #ifdef FEAT_EVAL expr = Tcl_GetStringFromObj(objv[objn], NULL); ! str = (char *)eval_to_string((char_u *)expr, NULL, TRUE); if (str == NULL) Tcl_SetResult(interp, _("invalid expression"), TCL_STATIC); else --- 1373,1379 ---- #ifdef FEAT_EVAL expr = Tcl_GetStringFromObj(objv[objn], NULL); ! str = (char *)eval_to_string((char_u *)expr, TRUE); if (str == NULL) Tcl_SetResult(interp, _("invalid expression"), TCL_STATIC); else *** ../vim-8.2.1048/src/map.c 2020-05-27 21:29:01.239636990 +0200 --- src/map.c 2020-06-24 19:46:19.373880564 +0200 *************** *** 1614,1620 **** save_cursor = curwin->w_cursor; save_msg_col = msg_col; save_msg_row = msg_row; ! p = eval_to_string(expr, NULL, FALSE); --textwinlock; --ex_normal_lock; curwin->w_cursor = save_cursor; --- 1614,1620 ---- save_cursor = curwin->w_cursor; save_msg_col = msg_col; save_msg_row = msg_row; ! p = eval_to_string(expr, FALSE); --textwinlock; --ex_normal_lock; curwin->w_cursor = save_cursor; *** ../vim-8.2.1048/src/quickfix.c 2020-06-11 19:35:48.741325222 +0200 --- src/quickfix.c 2020-06-24 19:50:04.225051674 +0200 *************** *** 7680,7686 **** // 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); if (tv != NULL) { if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL) --- 7680,7686 ---- // 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); if (tv != NULL) { if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL) *** ../vim-8.2.1048/src/regexp.c 2020-06-12 22:59:07.270097188 +0200 --- src/regexp.c 2020-06-24 19:46:29.061844831 +0200 *************** *** 2066,2072 **** clear_tv(&rettv); } else ! eval_result = eval_to_string(source + 2, NULL, TRUE); if (eval_result != NULL) { --- 2066,2072 ---- clear_tv(&rettv); } else ! eval_result = eval_to_string(source + 2, TRUE); if (eval_result != NULL) { *** ../vim-8.2.1048/src/register.c 2020-06-17 21:47:19.912798036 +0200 --- src/register.c 2020-06-24 19:46:39.081807894 +0200 *************** *** 136,142 **** return expr_copy; ++nested; ! rv = eval_to_string(expr_copy, NULL, TRUE); --nested; vim_free(expr_copy); return rv; --- 136,142 ---- return expr_copy; ++nested; ! rv = eval_to_string(expr_copy, TRUE); --nested; vim_free(expr_copy); return rv; *** ../vim-8.2.1048/src/screen.c 2020-05-31 16:41:04.646603340 +0200 --- src/screen.c 2020-06-24 19:46:48.553772925 +0200 *************** *** 1148,1154 **** curwin = wp; STRCPY(buf, "b:keymap_name"); // must be writable ++emsg_skip; ! s = p = eval_to_string(buf, NULL, FALSE); --emsg_skip; curbuf = old_curbuf; curwin = old_curwin; --- 1148,1154 ---- curwin = wp; STRCPY(buf, "b:keymap_name"); // must be writable ++emsg_skip; ! s = p = eval_to_string(buf, FALSE); --emsg_skip; curbuf = old_curbuf; curwin = old_curwin; *** ../vim-8.2.1048/src/userfunc.c 2020-06-24 18:37:28.359249374 +0200 --- src/userfunc.c 2020-06-24 19:54:47.112011055 +0200 *************** *** 3716,3722 **** eap->nextcmd = NULL; if ((*arg != NUL && *arg != '|' && *arg != '\n') ! && eval0(arg, &rettv, &eap->nextcmd, &evalarg) != FAIL) { if (!eap->skip) returning = do_return(eap, FALSE, TRUE, &rettv); --- 3716,3722 ---- eap->nextcmd = NULL; if ((*arg != NUL && *arg != '|' && *arg != '\n') ! && eval0(arg, &rettv, eap, &evalarg) != FAIL) { if (!eap->skip) returning = do_return(eap, FALSE, TRUE, &rettv); *************** *** 3773,3779 **** // 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) clear_tv(&rettv); --emsg_skip; return; --- 3773,3779 ---- // 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, NULL) != FAIL) clear_tv(&rettv); --emsg_skip; return; *** ../vim-8.2.1048/src/version.c 2020-06-24 19:05:23.899362149 +0200 --- src/version.c 2020-06-24 20:17:08.964409321 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1049, /**/ -- SIGFUN -- signature too funny (core dumped) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///