Patch 8.2.0056
Problem: Execution stack is incomplete and inefficient.
Solution: Introduce a proper execution stack and use it instead of
sourcing_name/sourcing_lnum. Create a string only when used.
Files: src/structs.h, src/globals.h, src/autocmd.c, src/buffer.c
src/debugger.c, src/ex_docmd.c, src/ex_eval.c, src/highlight.c,
src/main.c, src/map.c, src/message.c, src/proto/
scriptfile.pro,
src/scriptfile.c, src/option.c, src/profiler.c, src/spellfile.c,
src/term.c, src/testing.c, src/usercmd.c, src/userfunc.c,
src/kword_test.c, src/testdir/test_debugger.vim
*** ../vim-8.2.0055/src/structs.h 2019-12-25 18:14:10.481839651 +0100
--- src/structs.h 2019-12-29 19:12:06.660504770 +0100
***************
*** 1496,1501 ****
--- 1496,1503 ----
// used for s: variables
int uf_refcount; // reference count, see func_name_refcount()
funccall_T *uf_scoped; // l: local variables for closure
+ char_u *uf_name_exp; // if "uf_name[]" starts with SNR the name with
+ // "<SNR>" as a string, otherwise NULL
char_u uf_name[1]; // name of function (actually longer); can
// start with <SNR>123_ (<SNR> is K_SPECIAL
// KS_EXTRA KE_SNR)
***************
*** 1665,1670 ****
--- 1667,1704 ----
dict_T *pt_dict; // dict for "self"
};
+ typedef struct AutoPatCmd_S AutoPatCmd;
+
+ /*
+ * Entry in the execution stack "exestack".
+ */
+ typedef enum {
+ ETYPE_TOP, // toplevel
+ ETYPE_SCRIPT, // sourcing script, use es_info.sctx
+ ETYPE_UFUNC, // user function, use es_info.ufunc
+ ETYPE_AUCMD, // autocomand, use es_info.aucmd
+ ETYPE_MODELINE, // modeline, use es_info.sctx
+ ETYPE_EXCEPT, // exception, use es_info.exception
+ ETYPE_ARGS, // command line argument
+ ETYPE_ENV, // environment variable
+ ETYPE_INTERNAL, // internal operation
+ ETYPE_SPELL, // loading spell file
+ } etype_T;
+
+ typedef struct {
+ long es_lnum; // replaces "sourcing_lnum"
+ char_u *es_name; // replaces "sourcing_name"
+ etype_T es_type;
+ union {
+ sctx_T *sctx; // script and modeline info
+ #if defined(FEAT_EVAL)
+ ufunc_T *ufunc; // function info
+ #endif
+ AutoPatCmd *aucmd; // autocommand info
+ except_T *except; // exception info
+ } es_info;
+ } estack_T;
+
// Information returned by get_tty_info().
typedef struct {
int backspace; // what the Backspace key produces
*** ../vim-8.2.0055/src/globals.h 2019-12-27 13:49:19.984946890 +0100
--- src/globals.h 2019-12-29 16:39:23.656982200 +0100
***************
*** 266,273 ****
EXTERN int msg_no_more INIT(= FALSE); // don't use more prompt, truncate
// messages
! EXTERN char_u *sourcing_name INIT( = NULL);// name of error message source
! EXTERN linenr_T sourcing_lnum INIT(= 0); // line number of the source file
#ifdef FEAT_EVAL
EXTERN int ex_nesting_level INIT(= 0); // nesting level
--- 266,280 ----
EXTERN int msg_no_more INIT(= FALSE); // don't use more prompt, truncate
// messages
! /*
! * Stack of execution contexts. Each entry is an estack_T.
! * Current context is at ga_len - 1.
! */
! EXTERN garray_T exestack INIT(= {0 COMMA 0 COMMA sizeof(estack_T) COMMA 50 COMMA NULL});
! // name of error message source
! #define SOURCING_NAME (((estack_T *)exestack.ga_data)[exestack.ga_len - 1].es_name)
! // line number in the message source or zero
! #define SOURCING_LNUM (((estack_T *)exestack.ga_data)[exestack.ga_len - 1].es_lnum)
#ifdef FEAT_EVAL
EXTERN int ex_nesting_level INIT(= 0); // nesting level
*** ../vim-8.2.0055/src/autocmd.c 2019-11-30 20:32:37.000000000 +0100
--- src/autocmd.c 2019-12-29 16:39:45.052886815 +0100
***************
*** 218,224 ****
/*
* struct used to keep status while executing autocommands for an event.
*/
! typedef struct AutoPatCmd
{
AutoPat *curpat; // next AutoPat to examine
AutoCmd *nextcmd; // next AutoCmd to execute
--- 218,224 ----
/*
* struct used to keep status while executing autocommands for an event.
*/
! struct AutoPatCmd_S
{
AutoPat *curpat; // next AutoPat to examine
AutoCmd *nextcmd; // next AutoCmd to execute
***************
*** 229,236 ****
event_T event; // current event
int arg_bufnr; // Initially equal to <abuf>, set to zero when
// buf is deleted.
! struct AutoPatCmd *next; // chain of active apc-s for auto-invalidation
! } AutoPatCmd;
static AutoPatCmd *active_apc_list = NULL; // stack of active autocommands
--- 229,236 ----
event_T event; // current event
int arg_bufnr; // Initially equal to <abuf>, set to zero when
// buf is deleted.
! AutoPatCmd *next; // chain of active apc-s for auto-invalidation
! };
static AutoPatCmd *active_apc_list = NULL; // stack of active autocommands
***************
*** 1242,1248 ****
ac->cmd = vim_strsave(cmd);
#ifdef FEAT_EVAL
ac->script_ctx = current_sctx;
! ac->script_ctx.sc_lnum += sourcing_lnum;
#endif
if (ac->cmd == NULL)
{
--- 1242,1248 ----
ac->cmd = vim_strsave(cmd);
#ifdef FEAT_EVAL
ac->script_ctx = current_sctx;
! ac->script_ctx.sc_lnum += SOURCING_LNUM;
#endif
if (ac->cmd == NULL)
{
***************
*** 1805,1812 ****
int save_changed;
buf_T *old_curbuf;
int retval = FALSE;
- char_u *save_sourcing_name;
- linenr_T save_sourcing_lnum;
char_u *save_autocmd_fname;
int save_autocmd_fname_full;
int save_autocmd_bufnr;
--- 1805,1810 ----
***************
*** 2020,2029 ****
// Don't redraw while doing autocommands.
++RedrawingDisabled;
! save_sourcing_name = sourcing_name;
! sourcing_name = NULL; // don't free this one
! save_sourcing_lnum = sourcing_lnum;
! sourcing_lnum = 0; // no line number here
#ifdef FEAT_EVAL
save_current_sctx = current_sctx;
--- 2018,2026 ----
// Don't redraw while doing autocommands.
++RedrawingDisabled;
!
! // name and lnum are filled in later
! estack_push(ETYPE_AUCMD, NULL, 0);
#ifdef FEAT_EVAL
save_current_sctx = current_sctx;
***************
*** 2126,2134 ****
autocmd_busy = save_autocmd_busy;
filechangeshell_busy = FALSE;
autocmd_nested = save_autocmd_nested;
! vim_free(sourcing_name);
! sourcing_name = save_sourcing_name;
! sourcing_lnum = save_sourcing_lnum;
vim_free(autocmd_fname);
autocmd_fname = save_autocmd_fname;
autocmd_fname_full = save_autocmd_fname_full;
--- 2123,2130 ----
autocmd_busy = save_autocmd_busy;
filechangeshell_busy = FALSE;
autocmd_nested = save_autocmd_nested;
! vim_free(SOURCING_NAME);
! estack_pop();
vim_free(autocmd_fname);
autocmd_fname = save_autocmd_fname;
autocmd_fname_full = save_autocmd_fname_full;
***************
*** 2256,2263 ****
AutoCmd *cp;
char_u *name;
char *s;
! VIM_CLEAR(sourcing_name);
for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
{
--- 2252,2260 ----
AutoCmd *cp;
char_u *name;
char *s;
+ char_u **sourcing_namep = &SOURCING_NAME;
! VIM_CLEAR(*sourcing_namep);
for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
{
***************
*** 2277,2292 ****
{
name = event_nr2name(apc->event);
s = _("%s Autocommands for \"%s\"");
! sourcing_name = alloc(STRLEN(s)
+ STRLEN(name) + ap->patlen + 1);
! if (sourcing_name != NULL)
{
! sprintf((char *)sourcing_name, s,
(char *)name, (char *)ap->pat);
if (p_verbose >= 8)
{
verbose_enter();
! smsg(_("Executing %s"), sourcing_name);
verbose_leave();
}
}
--- 2274,2289 ----
{
name = event_nr2name(apc->event);
s = _("%s Autocommands for \"%s\"");
! *sourcing_namep = alloc(STRLEN(s)
+ STRLEN(name) + ap->patlen + 1);
! if (*sourcing_namep != NULL)
{
! sprintf((char *)*sourcing_namep, s,
(char *)name, (char *)ap->pat);
if (p_verbose >= 8)
{
verbose_enter();
! smsg(_("Executing %s"), *sourcing_namep);
verbose_leave();
}
}
*** ../vim-8.2.0055/src/buffer.c 2019-12-29 13:56:28.692861883 +0100
--- src/buffer.c 2019-12-29 16:17:22.877768244 +0100
***************
*** 5279,5286 ****
int vers;
int end;
int retval = OK;
- char_u *save_sourcing_name;
- linenr_T save_sourcing_lnum;
#ifdef FEAT_EVAL
sctx_T save_current_sctx;
#endif
--- 5279,5284 ----
***************
*** 5325,5334 ****
if (linecopy == NULL)
return FAIL;
! save_sourcing_lnum = sourcing_lnum;
! save_sourcing_name = sourcing_name;
! sourcing_lnum = lnum; // prepare for emsg()
! sourcing_name = (char_u *)"modelines";
end = FALSE;
while (end == FALSE)
--- 5323,5330 ----
if (linecopy == NULL)
return FAIL;
! // prepare for emsg()
! estack_push(ETYPE_MODELINE, (char_u *)"modelines", lnum);
end = FALSE;
while (end == FALSE)
***************
*** 5371,5377 ****
save_current_sctx = current_sctx;
current_sctx.sc_sid = SID_MODELINE;
current_sctx.sc_seq = 0;
! current_sctx.sc_lnum = 0;
current_sctx.sc_version = 1;
#endif
// Make sure no risky things are executed as a side effect.
--- 5367,5373 ----
save_current_sctx = current_sctx;
current_sctx.sc_sid = SID_MODELINE;
current_sctx.sc_seq = 0;
! current_sctx.sc_lnum = lnum;
current_sctx.sc_version = 1;
#endif
// Make sure no risky things are executed as a side effect.
***************
*** 5389,5397 ****
s = e + 1; // advance to next part
}
! sourcing_lnum = save_sourcing_lnum;
! sourcing_name = save_sourcing_name;
!
vim_free(linecopy);
}
return retval;
--- 5385,5391 ----
s = e + 1; // advance to next part
}
! estack_pop();
vim_free(linecopy);
}
return retval;
*** ../vim-8.2.0055/src/debugger.c 2019-12-25 18:14:10.481839651 +0100
--- src/debugger.c 2019-12-29 21:00:17.504117635 +0100
***************
*** 51,56 ****
--- 51,57 ----
int n;
char_u *cmdline = NULL;
char_u *p;
+ char_u *sname;
char *tail = NULL;
static int last_cmd = 0;
#define CMD_CONT 1
***************
*** 104,113 ****
vim_free(debug_newval);
debug_newval = NULL;
}
! if (sourcing_name != NULL)
! msg((char *)sourcing_name);
! if (sourcing_lnum != 0)
! smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd);
else
smsg(_("cmd: %s"), cmd);
--- 105,116 ----
vim_free(debug_newval);
debug_newval = NULL;
}
! sname = estack_sfile();
! if (sname != NULL)
! msg((char *)sname);
! vim_free(sname);
! if (SOURCING_LNUM != 0)
! smsg(_("line %ld: %s"), SOURCING_LNUM, cmd);
else
smsg(_("cmd: %s"), cmd);
***************
*** 300,313 ****
}
static int
! get_maxbacktrace_level(void)
{
char *p, *q;
int maxbacktrace = 0;
! if (sourcing_name != NULL)
{
! p = (char *)sourcing_name;
while ((q = strstr(p, "..")) != NULL)
{
p = q + 2;
--- 303,316 ----
}
static int
! get_maxbacktrace_level(char_u *sname)
{
char *p, *q;
int maxbacktrace = 0;
! if (sname != NULL)
{
! p = (char *)sname;
while ((q = strstr(p, "..")) != NULL)
{
p = q + 2;
***************
*** 341,367 ****
}
else
{
! int max = get_maxbacktrace_level();
if (debug_backtrace_level > max)
{
debug_backtrace_level = max;
smsg(_("frame at highest level: %d"), max);
}
}
}
static void
do_showbacktrace(char_u *cmd)
{
char *cur;
char *next;
int i = 0;
! int max = get_maxbacktrace_level();
! if (sourcing_name != NULL)
{
! cur = (char *)sourcing_name;
while (!got_int)
{
next = strstr(cur, "..");
--- 344,375 ----
}
else
{
! char_u *sname = estack_sfile();
! int max = get_maxbacktrace_level(sname);
if (debug_backtrace_level > max)
{
debug_backtrace_level = max;
smsg(_("frame at highest level: %d"), max);
}
+ vim_free(sname);
}
}
static void
do_showbacktrace(char_u *cmd)
{
+ char_u *sname;
char *cur;
char *next;
int i = 0;
! int max;
! sname = estack_sfile();
! max = get_maxbacktrace_level(sname);
! if (sname != NULL)
{
! cur = (char *)sname;
while (!got_int)
{
next = strstr(cur, "..");
***************
*** 377,385 ****
*next = '.';
cur = next + 2;
}
}
! if (sourcing_lnum != 0)
! smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd);
else
smsg(_("cmd: %s"), cmd);
}
--- 385,395 ----
*next = '.';
cur = next + 2;
}
+ vim_free(sname);
}
!
! if (SOURCING_LNUM != 0)
! smsg(_("line %ld: %s"), (long)SOURCING_LNUM, cmd);
else
smsg(_("cmd: %s"), cmd);
}
*** ../vim-8.2.0055/src/ex_docmd.c 2019-12-16 17:10:30.291144418 +0100
--- src/ex_docmd.c 2019-12-29 18:44:31.113192680 +0100
***************
*** 703,709 ****
}
else if (getline_equal(fgetline, cookie, getsourceline))
{
! fname = sourcing_name;
breakpoint = source_breakpoint(real_cookie);
dbg_tick = source_dbg_tick(real_cookie);
}
--- 703,709 ----
}
else if (getline_equal(fgetline, cookie, getsourceline))
{
! fname = SOURCING_NAME;
breakpoint = source_breakpoint(real_cookie);
dbg_tick = source_dbg_tick(real_cookie);
}
***************
*** 819,840 ****
{
*breakpoint = dbg_find_breakpoint(
getline_equal(fgetline, cookie, getsourceline),
! fname, sourcing_lnum);
*dbg_tick = debug_tick;
}
next_cmdline = ((wcmd_T *)(lines_ga.ga_data))[current_line].line;
! sourcing_lnum = ((wcmd_T *)(lines_ga.ga_data))[current_line].lnum;
// Did we encounter a breakpoint?
if (breakpoint != NULL && *breakpoint != 0
! && *breakpoint <= sourcing_lnum)
{
! dbg_breakpoint(fname, sourcing_lnum);
// Find next breakpoint.
*breakpoint = dbg_find_breakpoint(
getline_equal(fgetline, cookie, getsourceline),
! fname, sourcing_lnum);
*dbg_tick = debug_tick;
}
# ifdef FEAT_PROFILE
--- 819,840 ----
{
*breakpoint = dbg_find_breakpoint(
getline_equal(fgetline, cookie, getsourceline),
! fname, SOURCING_LNUM);
*dbg_tick = debug_tick;
}
next_cmdline = ((wcmd_T *)(lines_ga.ga_data))[current_line].line;
! SOURCING_LNUM = ((wcmd_T *)(lines_ga.ga_data))[current_line].lnum;
// Did we encounter a breakpoint?
if (breakpoint != NULL && *breakpoint != 0
! && *breakpoint <= SOURCING_LNUM)
{
! dbg_breakpoint(fname, SOURCING_LNUM);
// Find next breakpoint.
*breakpoint = dbg_find_breakpoint(
getline_equal(fgetline, cookie, getsourceline),
! fname, SOURCING_LNUM);
*dbg_tick = debug_tick;
}
# ifdef FEAT_PROFILE
***************
*** 963,970 ****
}
}
! if (p_verbose >= 15 && sourcing_name != NULL)
! msg_verbose_cmd(sourcing_lnum, cmdline_copy);
/*
* 2. Execute one '|' separated command.
--- 963,970 ----
}
}
! if (p_verbose >= 15 && SOURCING_NAME != NULL)
! msg_verbose_cmd(SOURCING_LNUM, cmdline_copy);
/*
* 2. Execute one '|' separated command.
***************
*** 1081,1087 ****
// Check for the next breakpoint after a watchexpression
if (breakpoint != NULL && has_watchexpr())
{
! *breakpoint = dbg_find_breakpoint(FALSE, fname, sourcing_lnum);
*dbg_tick = debug_tick;
}
--- 1081,1087 ----
// Check for the next breakpoint after a watchexpression
if (breakpoint != NULL && has_watchexpr())
{
! *breakpoint = dbg_find_breakpoint(FALSE, fname, SOURCING_LNUM);
*dbg_tick = debug_tick;
}
***************
*** 1092,1098 ****
{
if (lines_ga.ga_len > 0)
{
! sourcing_lnum =
((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
free_cmdlines(&lines_ga);
}
--- 1092,1098 ----
{
if (lines_ga.ga_len > 0)
{
! SOURCING_LNUM =
((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
free_cmdlines(&lines_ga);
}
***************
*** 1234,1241 ****
if (did_throw)
{
void *p = NULL;
- char_u *saved_sourcing_name;
- int saved_sourcing_lnum;
struct msglist *messages = NULL, *next;
/*
--- 1234,1239 ----
***************
*** 1260,1269 ****
break;
}
! saved_sourcing_name = sourcing_name;
! saved_sourcing_lnum = sourcing_lnum;
! sourcing_name = current_exception->throw_name;
! sourcing_lnum = current_exception->throw_lnum;
current_exception->throw_name = NULL;
discard_current_exception(); // uses IObuff if 'verbose'
--- 1258,1265 ----
break;
}
! estack_push(ETYPE_EXCEPT, current_exception->throw_name,
! current_exception->throw_lnum);
current_exception->throw_name = NULL;
discard_current_exception(); // uses IObuff if 'verbose'
***************
*** 1287,1295 ****
emsg(p);
vim_free(p);
}
! vim_free(sourcing_name);
! sourcing_name = saved_sourcing_name;
! sourcing_lnum = saved_sourcing_lnum;
}
/*
--- 1283,1290 ----
emsg(p);
vim_free(p);
}
! vim_free(SOURCING_NAME);
! estack_pop();
}
/*
***************
*** 1428,1434 ****
KeyTyped = FALSE;
++cp->current_line;
wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line;
! sourcing_lnum = wp->lnum;
return vim_strsave(wp->line);
}
--- 1423,1429 ----
KeyTyped = FALSE;
++cp->current_line;
wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line;
! SOURCING_LNUM = wp->lnum;
return vim_strsave(wp->line);
}
***************
*** 1441,1447 ****
if (ga_grow(gap, 1) == FAIL)
return FAIL;
((wcmd_T *)(gap->ga_data))[gap->ga_len].line = vim_strsave(line);
! ((wcmd_T *)(gap->ga_data))[gap->ga_len].lnum = sourcing_lnum;
++gap->ga_len;
return OK;
}
--- 1436,1442 ----
if (ga_grow(gap, 1) == FAIL)
return FAIL;
((wcmd_T *)(gap->ga_data))[gap->ga_len].line = vim_strsave(line);
! ((wcmd_T *)(gap->ga_data))[gap->ga_len].lnum = SOURCING_LNUM;
++gap->ga_len;
return OK;
}
***************
*** 8171,8203 ****
break;
case SPEC_SFILE: // file name for ":so" command
! result = sourcing_name;
if (result == NULL)
{
*errormsg = _("E498: no :source file name to substitute for \"<sfile>\"");
return NULL;
}
break;
case SPEC_SLNUM: // line in file for ":so" command
! if (sourcing_name == NULL || sourcing_lnum == 0)
{
*errormsg = _("E842: no line number to use for \"<slnum>\"");
return NULL;
}
! sprintf((char *)strbuf, "%ld", (long)sourcing_lnum);
result = strbuf;
break;
#ifdef FEAT_EVAL
case SPEC_SFLNUM: // line in script file
! if (current_sctx.sc_lnum + sourcing_lnum == 0)
{
*errormsg = _("E961: no line number to use for \"<sflnum>\"");
return NULL;
}
sprintf((char *)strbuf, "%ld",
! (long)(current_sctx.sc_lnum + sourcing_lnum));
result = strbuf;
break;
#endif
--- 8166,8199 ----
break;
case SPEC_SFILE: // file name for ":so" command
! result = estack_sfile();
if (result == NULL)
{
*errormsg = _("E498: no :source file name to substitute for \"<sfile>\"");
return NULL;
}
+ resultbuf = result; // remember allocated string
break;
case SPEC_SLNUM: // line in file for ":so" command
! if (SOURCING_NAME == NULL || SOURCING_LNUM == 0)
{
*errormsg = _("E842: no line number to use for \"<slnum>\"");
return NULL;
}
! sprintf((char *)strbuf, "%ld", SOURCING_LNUM);
result = strbuf;
break;
#ifdef FEAT_EVAL
case SPEC_SFLNUM: // line in script file
! if (current_sctx.sc_lnum + SOURCING_LNUM == 0)
{
*errormsg = _("E961: no line number to use for \"<sflnum>\"");
return NULL;
}
sprintf((char *)strbuf, "%ld",
! (long)(current_sctx.sc_lnum + SOURCING_LNUM));
result = strbuf;
break;
#endif
*** ../vim-8.2.0055/src/ex_eval.c 2019-12-16 17:10:30.291144418 +0100
--- src/ex_eval.c 2019-12-29 22:50:57.021592930 +0100
***************
*** 534,548 ****
goto nomem;
excp->type = type;
! excp->throw_name = vim_strsave(sourcing_name == NULL
! ? (char_u *)"" : sourcing_name);
if (excp->throw_name == NULL)
{
if (should_free)
vim_free(excp->value);
goto nomem;
}
! excp->throw_lnum = sourcing_lnum;
if (p_verbose >= 13 || debug_break_level > 0)
{
--- 534,549 ----
goto nomem;
excp->type = type;
! excp->throw_name = estack_sfile();
! if (excp->throw_name == NULL)
! excp->throw_name = vim_strsave((char_u *)"");
if (excp->throw_name == NULL)
{
if (should_free)
vim_free(excp->value);
goto nomem;
}
! excp->throw_lnum = SOURCING_LNUM;
if (p_verbose >= 13 || debug_break_level > 0)
{
*** ../vim-8.2.0055/src/highlight.c 2019-12-24 15:38:18.059988789 +0100
--- src/highlight.c 2019-12-29 16:41:16.584486153 +0100
***************
*** 748,754 ****
if (to_id > 0 && !forceit && !init
&& hl_has_settings(from_id - 1, dodefault))
{
! if (sourcing_name == NULL && !dodefault)
emsg(_("E414: group has settings, highlight link ignored"));
}
else if (HL_TABLE()[from_id - 1].sg_link != to_id
--- 748,754 ----
if (to_id > 0 && !forceit && !init
&& hl_has_settings(from_id - 1, dodefault))
{
! if (SOURCING_NAME == NULL && !dodefault)
emsg(_("E414: group has settings, highlight link ignored"));
}
else if (HL_TABLE()[from_id - 1].sg_link != to_id
***************
*** 763,769 ****
HL_TABLE()[from_id - 1].sg_link = to_id;
#ifdef FEAT_EVAL
HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx;
! HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += sourcing_lnum;
#endif
HL_TABLE()[from_id - 1].sg_cleared = FALSE;
redraw_all_later(SOME_VALID);
--- 763,769 ----
HL_TABLE()[from_id - 1].sg_link = to_id;
#ifdef FEAT_EVAL
HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx;
! HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += SOURCING_LNUM;
#endif
HL_TABLE()[from_id - 1].sg_cleared = FALSE;
redraw_all_later(SOME_VALID);
***************
*** 1518,1524 ****
set_hl_attr(idx);
#ifdef FEAT_EVAL
HL_TABLE()[idx].sg_script_ctx = current_sctx;
! HL_TABLE()[idx].sg_script_ctx.sc_lnum += sourcing_lnum;
#endif
}
--- 1518,1524 ----
set_hl_attr(idx);
#ifdef FEAT_EVAL
HL_TABLE()[idx].sg_script_ctx = current_sctx;
! HL_TABLE()[idx].sg_script_ctx.sc_lnum += SOURCING_LNUM;
#endif
}
*** ../vim-8.2.0055/src/main.c 2019-12-23 22:59:14.264820697 +0100
--- src/main.c 2019-12-29 16:26:59.455699649 +0100
***************
*** 911,916 ****
--- 911,917 ----
void
common_init(mparm_T *paramp)
{
+ estack_init();
cmdline_init();
(void)mb_init(); // init mb_bytelen_tab[] to ones
***************
*** 3089,3101 ****
if (cnt > 0)
{
curwin->w_cursor.lnum = 0; // just in case..
! sourcing_name = (char_u *)_("pre-vimrc command line");
# ifdef FEAT_EVAL
current_sctx.sc_sid = SID_CMDARG;
# endif
for (i = 0; i < cnt; ++i)
do_cmdline_cmd(cmds[i]);
! sourcing_name = NULL;
# ifdef FEAT_EVAL
current_sctx.sc_sid = 0;
# endif
--- 3090,3102 ----
if (cnt > 0)
{
curwin->w_cursor.lnum = 0; // just in case..
! estack_push(ETYPE_ARGS, (char_u *)_("pre-vimrc command line"), 0);
# ifdef FEAT_EVAL
current_sctx.sc_sid = SID_CMDARG;
# endif
for (i = 0; i < cnt; ++i)
do_cmdline_cmd(cmds[i]);
! estack_pop();
# ifdef FEAT_EVAL
current_sctx.sc_sid = 0;
# endif
***************
*** 3119,3125 ****
msg_scroll = TRUE;
if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
curwin->w_cursor.lnum = 0;
! sourcing_name = (char_u *)"command line";
#ifdef FEAT_EVAL
current_sctx.sc_sid = SID_CARG;
current_sctx.sc_seq = 0;
--- 3120,3126 ----
msg_scroll = TRUE;
if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
curwin->w_cursor.lnum = 0;
! estack_push(ETYPE_ARGS, (char_u *)"command line", 0);
#ifdef FEAT_EVAL
current_sctx.sc_sid = SID_CARG;
current_sctx.sc_seq = 0;
***************
*** 3130,3136 ****
if (parmp->cmds_tofree[i])
vim_free(parmp->commands[i]);
}
! sourcing_name = NULL;
#ifdef FEAT_EVAL
current_sctx.sc_sid = 0;
#endif
--- 3131,3137 ----
if (parmp->cmds_tofree[i])
vim_free(parmp->commands[i]);
}
! estack_pop();
#ifdef FEAT_EVAL
current_sctx.sc_sid = 0;
#endif
***************
*** 3336,3343 ****
int is_viminit) // when TRUE, called for VIMINIT
{
char_u *initstr;
- char_u *save_sourcing_name;
- linenr_T save_sourcing_lnum;
#ifdef FEAT_EVAL
sctx_T save_current_sctx;
#endif
--- 3337,3342 ----
***************
*** 3346,3355 ****
{
if (is_viminit)
vimrc_found(NULL, NULL);
! save_sourcing_name = sourcing_name;
! save_sourcing_lnum = sourcing_lnum;
! sourcing_name = env;
! sourcing_lnum = 0;
#ifdef FEAT_EVAL
save_current_sctx = current_sctx;
current_sctx.sc_sid = SID_ENV;
--- 3345,3351 ----
{
if (is_viminit)
vimrc_found(NULL, NULL);
! estack_push(ETYPE_ENV, env, 0);
#ifdef FEAT_EVAL
save_current_sctx = current_sctx;
current_sctx.sc_sid = SID_ENV;
***************
*** 3358,3365 ****
current_sctx.sc_version = 1;
#endif
do_cmdline_cmd(initstr);
! sourcing_name = save_sourcing_name;
! sourcing_lnum = save_sourcing_lnum;
#ifdef FEAT_EVAL
current_sctx = save_current_sctx;
#endif
--- 3354,3361 ----
current_sctx.sc_version = 1;
#endif
do_cmdline_cmd(initstr);
!
! estack_pop();
#ifdef FEAT_EVAL
current_sctx = save_current_sctx;
#endif
*** ../vim-8.2.0055/src/map.c 2019-11-02 22:51:27.000000000 +0100
--- src/map.c 2019-12-29 16:41:26.320444196 +0100
***************
*** 697,703 ****
#ifdef FEAT_EVAL
mp->m_expr = expr;
mp->m_script_ctx = current_sctx;
! mp->m_script_ctx.sc_lnum += sourcing_lnum;
#endif
did_it = TRUE;
}
--- 697,703 ----
#ifdef FEAT_EVAL
mp->m_expr = expr;
mp->m_script_ctx = current_sctx;
! mp->m_script_ctx.sc_lnum += SOURCING_LNUM;
#endif
did_it = TRUE;
}
***************
*** 796,802 ****
#ifdef FEAT_EVAL
mp->m_expr = expr;
mp->m_script_ctx = current_sctx;
! mp->m_script_ctx.sc_lnum += sourcing_lnum;
#endif
// add the new entry in front of the abbrlist or maphash[] list
--- 796,802 ----
#ifdef FEAT_EVAL
mp->m_expr = expr;
mp->m_script_ctx = current_sctx;
! mp->m_script_ctx.sc_lnum += SOURCING_LNUM;
#endif
// add the new entry in front of the abbrlist or maphash[] list
***************
*** 1915,1928 ****
char_u *p;
int i;
char_u buf[3];
- char_u *save_name;
int abbr;
int hash;
buf_T *bp;
validate_maphash();
! save_name = sourcing_name;
! sourcing_name = (char_u *)"mappings"; // avoids giving error messages
// Do this once for each buffer, and then once for global
// mappings/abbreviations with bp == NULL
--- 1915,1927 ----
char_u *p;
int i;
char_u buf[3];
int abbr;
int hash;
buf_T *bp;
validate_maphash();
! // avoids giving error messages
! estack_push(ETYPE_INTERNAL, (char_u *)"mappings", 0);
// Do this once for each buffer, and then once for global
// mappings/abbreviations with bp == NULL
***************
*** 1979,1985 ****
if (bp == NULL)
break;
}
! sourcing_name = save_name;
}
#if defined(FEAT_EVAL) || defined(PROTO)
--- 1978,1984 ----
if (bp == NULL)
break;
}
! estack_pop();
}
#if defined(FEAT_EVAL) || defined(PROTO)
*** ../vim-8.2.0055/src/message.c 2019-12-23 22:59:14.260820709 +0100
--- src/message.c 2019-12-29 20:09:53.238576174 +0100
***************
*** 434,448 ****
}
/*
! * Return TRUE if "sourcing_name" differs from "last_sourcing_name".
*/
static int
other_sourcing_name(void)
{
! if (sourcing_name != NULL)
{
if (last_sourcing_name != NULL)
! return STRCMP(sourcing_name, last_sourcing_name) != 0;
return TRUE;
}
return FALSE;
--- 434,448 ----
}
/*
! * Return TRUE if "SOURCING_NAME" differs from "last_sourcing_name".
*/
static int
other_sourcing_name(void)
{
! if (SOURCING_NAME != NULL)
{
if (last_sourcing_name != NULL)
! return STRCMP(SOURCING_NAME, last_sourcing_name) != 0;
return TRUE;
}
return FALSE;
***************
*** 458,469 ****
{
char_u *Buf, *p;
! if (sourcing_name != NULL && other_sourcing_name())
{
p = (char_u *)_("Error detected while processing %s:");
! Buf = alloc(STRLEN(sourcing_name) + STRLEN(p));
if (Buf != NULL)
! sprintf((char *)Buf, (char *)p, sourcing_name);
return Buf;
}
return NULL;
--- 458,476 ----
{
char_u *Buf, *p;
! if (SOURCING_NAME != NULL && other_sourcing_name())
{
+ char_u *sname = estack_sfile();
+ char_u *tofree = sname;
+
+ if (sname == NULL)
+ sname = SOURCING_NAME;
+
p = (char_u *)_("Error detected while processing %s:");
! Buf = alloc(STRLEN(sname) + STRLEN(p));
if (Buf != NULL)
! sprintf((char *)Buf, (char *)p, sname);
! vim_free(tofree);
return Buf;
}
return NULL;
***************
*** 481,494 ****
// lnum is 0 when executing a command from the command line
// argument, we don't want a line number then
! if (sourcing_name != NULL
! && (other_sourcing_name() || sourcing_lnum != last_sourcing_lnum)
! && sourcing_lnum != 0)
{
p = (char_u *)_("line %4ld:");
Buf = alloc(STRLEN(p) + 20);
if (Buf != NULL)
! sprintf((char *)Buf, (char *)p, (long)sourcing_lnum);
return Buf;
}
return NULL;
--- 488,501 ----
// lnum is 0 when executing a command from the command line
// argument, we don't want a line number then
! if (SOURCING_NAME != NULL
! && (other_sourcing_name() || SOURCING_LNUM != last_sourcing_lnum)
! && SOURCING_LNUM != 0)
{
p = (char_u *)_("line %4ld:");
Buf = alloc(STRLEN(p) + 20);
if (Buf != NULL)
! sprintf((char *)Buf, (char *)p, (long)SOURCING_LNUM);
return Buf;
}
return NULL;
***************
*** 516,532 ****
{
msg_attr((char *)p, HL_ATTR(HLF_N));
vim_free(p);
! last_sourcing_lnum = sourcing_lnum; // only once for each line
}
// remember the last sourcing name printed, also when it's empty
! if (sourcing_name == NULL || other_sourcing_name())
{
vim_free(last_sourcing_name);
! if (sourcing_name == NULL)
last_sourcing_name = NULL;
else
! last_sourcing_name = vim_strsave(sourcing_name);
}
--no_wait_return;
}
--- 523,539 ----
{
msg_attr((char *)p, HL_ATTR(HLF_N));
vim_free(p);
! last_sourcing_lnum = SOURCING_LNUM; // only once for each line
}
// remember the last sourcing name printed, also when it's empty
! if (SOURCING_NAME == NULL || other_sourcing_name())
{
vim_free(last_sourcing_name);
! if (SOURCING_NAME == NULL)
last_sourcing_name = NULL;
else
! last_sourcing_name = vim_strsave(SOURCING_NAME);
}
--no_wait_return;
}
***************
*** 2312,2318 ****
#ifdef FEAT_EVAL
if (*get_vim_var_str(VV_SCROLLSTART) == NUL)
{
! char_u *p = sourcing_name;
char_u *tofree = NULL;
int len;
--- 2319,2325 ----
#ifdef FEAT_EVAL
if (*get_vim_var_str(VV_SCROLLSTART) == NUL)
{
! char_u *p = SOURCING_NAME;
char_u *tofree = NULL;
int len;
***************
*** 2327,2333 ****
if (tofree != NULL)
{
vim_snprintf((char *)tofree, len, _("%s line %ld"),
! p, (long)sourcing_lnum);
p = tofree;
}
}
--- 2334,2340 ----
if (tofree != NULL)
{
vim_snprintf((char *)tofree, len, _("%s line %ld"),
! p, (long)SOURCING_LNUM);
p = tofree;
}
}
*** ../vim-8.2.0055/src/proto/
scriptfile.pro 2019-12-12 12:55:32.000000000 +0100
--- src/proto/
scriptfile.pro 2019-12-29 18:48:29.056368319 +0100
***************
*** 1,4 ****
--- 1,9 ----
/* scriptfile.c */
+ void estack_init(void);
+ estack_T *estack_push(etype_T type, char_u *name, long lnum);
+ void estack_push_ufunc(etype_T type, ufunc_T *ufunc, long lnum);
+ void estack_pop(void);
+ char_u *estack_sfile(void);
void ex_runtime(exarg_T *eap);
int do_in_path(char_u *path, char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
int do_in_runtimepath(char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
*** ../vim-8.2.0055/src/scriptfile.c 2019-12-05 21:04:06.000000000 +0100
--- src/scriptfile.c 2019-12-29 20:57:44.184820163 +0100
***************
*** 19,24 ****
--- 19,140 ----
#endif
/*
+ * Initialize the execution stack.
+ */
+ void
+ estack_init(void)
+ {
+ estack_T *entry;
+
+ if (ga_grow(&exestack, 10) == FAIL)
+ mch_exit(0);
+ entry = ((estack_T *)exestack.ga_data) + exestack.ga_len;
+ entry->es_type = ETYPE_TOP;
+ entry->es_name = NULL;
+ entry->es_lnum = 0;
+ entry->es_info.ufunc = NULL;
+ ++exestack.ga_len;
+ }
+
+ /*
+ * Add an item to the execution stack.
+ * Returns the new entry or NULL when out of memory.
+ */
+ estack_T *
+ estack_push(etype_T type, char_u *name, long lnum)
+ {
+ estack_T *entry;
+
+ // If memory allocation fails then we'll pop more than we push, eventually
+ // at the top level it will be OK again.
+ if (ga_grow(&exestack, 1) == OK)
+ {
+ entry = ((estack_T *)exestack.ga_data) + exestack.ga_len;
+ entry->es_type = type;
+ entry->es_name = name;
+ entry->es_lnum = lnum;
+ entry->es_info.ufunc = NULL;
+ ++exestack.ga_len;
+ return entry;
+ }
+ return NULL;
+ }
+
+ /*
+ * Add a user function to the execution stack.
+ */
+ void
+ estack_push_ufunc(etype_T type, ufunc_T *ufunc, long lnum)
+ {
+ estack_T *entry = estack_push(type,
+ ufunc->uf_name_exp != NULL
+ ? ufunc->uf_name_exp : ufunc->uf_name, lnum);
+ if (entry != NULL)
+ entry->es_info.ufunc = ufunc;
+ }
+
+ /*
+ * Take an item off of the execution stack.
+ */
+ void
+ estack_pop(void)
+ {
+ if (exestack.ga_len > 1)
+ --exestack.ga_len;
+ }
+
+ /*
+ * Get the current value for <sfile> in allocated memory.
+ */
+ char_u *
+ estack_sfile(void)
+ {
+ int len;
+ int idx;
+ estack_T *entry;
+ char *res;
+ int done;
+
+ entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
+ if (entry->es_name == NULL)
+ return NULL;
+ if (entry->es_info.ufunc == NULL)
+ return vim_strsave(entry->es_name);
+
+ // For a function we compose the call stack, as it was done in the past:
+ // "function One[123]..Two[456]..Three"
+ len = STRLEN(entry->es_name) + 10;
+ for (idx = exestack.ga_len - 2; idx >= 0; --idx)
+ {
+ entry = ((estack_T *)exestack.ga_data) + idx;
+ if (entry->es_name == NULL || entry->es_info.ufunc == NULL)
+ {
+ ++idx;
+ break;
+ }
+ len += STRLEN(entry->es_name) + 15;
+ }
+
+ res = (char *)alloc(len);
+ if (res != NULL)
+ {
+ STRCPY(res, "function ");
+ while (idx < exestack.ga_len - 1)
+ {
+ done = STRLEN(res);
+ entry = ((estack_T *)exestack.ga_data) + idx;
+ vim_snprintf(res + done, len - done, "%s[%ld]..",
+ entry->es_name, entry->es_lnum);
+ ++idx;
+ }
+ done = STRLEN(res);
+ entry = ((estack_T *)exestack.ga_data) + idx;
+ vim_snprintf(res + done, len - done, "%s", entry->es_name);
+ }
+ return (char_u *)res;
+ }
+
+ /*
* ":runtime [what] {name}"
*/
void
***************
*** 947,954 ****
int is_vimrc) // DOSO_ value
{
struct source_cookie cookie;
- char_u *save_sourcing_name;
- linenr_T save_sourcing_lnum;
char_u *p;
char_u *fname_exp;
char_u *firstline = NULL;
--- 1063,1068 ----
***************
*** 1039,1049 ****
if (p_verbose > 0)
{
verbose_enter();
! if (sourcing_name == NULL)
smsg(_("could not source \"%s\""), fname);
else
smsg(_("line %ld: could not source \"%s\""),
! sourcing_lnum, fname);
verbose_leave();
}
goto theend;
--- 1153,1163 ----
if (p_verbose > 0)
{
verbose_enter();
! if (SOURCING_NAME == NULL)
smsg(_("could not source \"%s\""), fname);
else
smsg(_("line %ld: could not source \"%s\""),
! SOURCING_LNUM, fname);
verbose_leave();
}
goto theend;
***************
*** 1055,1065 ****
if (p_verbose > 1)
{
verbose_enter();
! if (sourcing_name == NULL)
smsg(_("sourcing \"%s\""), fname);
else
! smsg(_("line %ld: sourcing \"%s\""),
! sourcing_lnum, fname);
verbose_leave();
}
if (is_vimrc == DOSO_VIMRC)
--- 1169,1178 ----
if (p_verbose > 1)
{
verbose_enter();
! if (SOURCING_NAME == NULL)
smsg(_("sourcing \"%s\""), fname);
else
! smsg(_("line %ld: sourcing \"%s\""), SOURCING_LNUM, fname);
verbose_leave();
}
if (is_vimrc == DOSO_VIMRC)
***************
*** 1090,1099 ****
#endif
// Keep the sourcing name/lnum, for recursive calls.
! save_sourcing_name = sourcing_name;
! sourcing_name = fname_exp;
! save_sourcing_lnum = sourcing_lnum;
! sourcing_lnum = 0;
#ifdef STARTUPTIME
if (time_fd != NULL)
--- 1203,1209 ----
#endif
// Keep the sourcing name/lnum, for recursive calls.
! estack_push(ETYPE_SCRIPT, fname_exp, 0);
#ifdef STARTUPTIME
if (time_fd != NULL)
***************
*** 1233,1246 ****
if (got_int)
emsg(_(e_interr));
! sourcing_name = save_sourcing_name;
! sourcing_lnum = save_sourcing_lnum;
if (p_verbose > 1)
{
verbose_enter();
smsg(_("finished sourcing %s"), fname);
! if (sourcing_name != NULL)
! smsg(_("continuing in %s"), sourcing_name);
verbose_leave();
}
#ifdef STARTUPTIME
--- 1343,1355 ----
if (got_int)
emsg(_(e_interr));
! estack_pop();
if (p_verbose > 1)
{
verbose_enter();
smsg(_("finished sourcing %s"), fname);
! if (SOURCING_NAME != NULL)
! smsg(_("continuing in %s"), SOURCING_NAME);
verbose_leave();
}
#ifdef STARTUPTIME
***************
*** 1381,1387 ****
{
return fgetline == getsourceline
? ((struct source_cookie *)cookie)->sourcing_lnum
! : sourcing_lnum;
}
static char_u *
--- 1490,1496 ----
{
return fgetline == getsourceline
? ((struct source_cookie *)cookie)->sourcing_lnum
! : SOURCING_LNUM;
}
static char_u *
***************
*** 1507,1513 ****
// If breakpoints have been added/deleted need to check for it.
if (sp->dbg_tick < debug_tick)
{
! sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
sp->dbg_tick = debug_tick;
}
# ifdef FEAT_PROFILE
--- 1616,1622 ----
// If breakpoints have been added/deleted need to check for it.
if (sp->dbg_tick < debug_tick)
{
! sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, SOURCING_LNUM);
sp->dbg_tick = debug_tick;
}
# ifdef FEAT_PROFILE
***************
*** 1517,1523 ****
#endif
// Set the current sourcing line number.
! sourcing_lnum = sp->sourcing_lnum + 1;
// Get current line. If there is a read-ahead line, use it, otherwise get
// one now.
--- 1626,1632 ----
#endif
// Set the current sourcing line number.
! SOURCING_LNUM = sp->sourcing_lnum + 1;
// Get current line. If there is a read-ahead line, use it, otherwise get
// one now.
***************
*** 1602,1612 ****
#ifdef FEAT_EVAL
// Did we encounter a breakpoint?
! if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum)
{
! dbg_breakpoint(sp->fname, sourcing_lnum);
// Find next breakpoint.
! sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
sp->dbg_tick = debug_tick;
}
#endif
--- 1711,1721 ----
#ifdef FEAT_EVAL
// Did we encounter a breakpoint?
! if (sp->breakpoint != 0 && sp->breakpoint <= SOURCING_LNUM)
{
! dbg_breakpoint(sp->fname, SOURCING_LNUM);
// Find next breakpoint.
! sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, SOURCING_LNUM);
sp->dbg_tick = debug_tick;
}
#endif
*** ../vim-8.2.0055/src/option.c 2019-12-05 20:11:19.000000000 +0100
--- src/option.c 2019-12-29 16:41:30.196427514 +0100
***************
*** 2435,2441 ****
int indir = (int)options[opt_idx].indir;
sctx_T new_script_ctx = script_ctx;
! new_script_ctx.sc_lnum += sourcing_lnum;
// Remember where the option was set. For local options need to do that
// in the buffer or window structure.
--- 2435,2441 ----
int indir = (int)options[opt_idx].indir;
sctx_T new_script_ctx = script_ctx;
! new_script_ctx.sc_lnum += SOURCING_LNUM;
// Remember where the option was set. For local options need to do that
// in the buffer or window structure.
*** ../vim-8.2.0055/src/profiler.c 2019-09-18 22:00:33.000000000 +0200
--- src/profiler.c 2019-12-29 16:42:33.308158473 +0100
***************
*** 602,611 ****
funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func;
! if (fp->uf_profiling && sourcing_lnum >= 1
! && sourcing_lnum <= fp->uf_lines.ga_len)
{
! fp->uf_tml_idx = sourcing_lnum - 1;
// Skip continuation lines.
while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
--fp->uf_tml_idx;
--- 602,611 ----
funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func;
! if (fp->uf_profiling && SOURCING_LNUM >= 1
! && SOURCING_LNUM <= fp->uf_lines.ga_len)
{
! fp->uf_tml_idx = SOURCING_LNUM - 1;
// Skip continuation lines.
while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
--fp->uf_tml_idx;
***************
*** 906,918 ****
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
return;
si = &SCRIPT_ITEM(current_sctx.sc_sid);
! if (si->sn_prof_on && sourcing_lnum >= 1)
{
// Grow the array before starting the timer, so that the time spent
// here isn't counted.
(void)ga_grow(&si->sn_prl_ga,
! (int)(sourcing_lnum - si->sn_prl_ga.ga_len));
! si->sn_prl_idx = sourcing_lnum - 1;
while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
{
--- 906,918 ----
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
return;
si = &SCRIPT_ITEM(current_sctx.sc_sid);
! if (si->sn_prof_on && SOURCING_LNUM >= 1)
{
// Grow the array before starting the timer, so that the time spent
// here isn't counted.
(void)ga_grow(&si->sn_prl_ga,
! (int)(SOURCING_LNUM - si->sn_prl_ga.ga_len));
! si->sn_prl_idx = SOURCING_LNUM - 1;
while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
{
*** ../vim-8.2.0055/src/spellfile.c 2019-12-05 21:20:39.000000000 +0100
--- src/spellfile.c 2019-12-29 16:33:07.918397631 +0100
***************
*** 349,356 ****
int i;
int n;
int len;
- char_u *save_sourcing_name = sourcing_name;
- linenr_T save_sourcing_lnum = sourcing_lnum;
slang_T *lp = NULL;
int c = 0;
int res;
--- 349,354 ----
***************
*** 393,400 ****
lp = old_lp;
// Set sourcing_name, so that error messages mention the file name.
! sourcing_name = fname;
! sourcing_lnum = 0;
/*
* <HEADER>: <fileID>
--- 391,397 ----
lp = old_lp;
// Set sourcing_name, so that error messages mention the file name.
! estack_push(ETYPE_SPELL, fname, 0);
/*
* <HEADER>: <fileID>
***************
*** 581,588 ****
endOK:
if (fd != NULL)
fclose(fd);
! sourcing_name = save_sourcing_name;
! sourcing_lnum = save_sourcing_lnum;
return lp;
}
--- 578,584 ----
endOK:
if (fd != NULL)
fclose(fd);
! estack_pop();
return lp;
}
*** ../vim-8.2.0055/src/term.c 2019-12-07 17:34:32.000000000 +0100
--- src/term.c 2019-12-29 16:34:24.690127317 +0100
***************
*** 2277,2283 ****
}
#endif
! if (sourcing_name == NULL)
{
#ifdef HAVE_TGETENT
if (error_msg != NULL)
--- 2277,2283 ----
}
#endif
! if (SOURCING_NAME == NULL)
{
#ifdef HAVE_TGETENT
if (error_msg != NULL)
*** ../vim-8.2.0055/src/testing.c 2019-12-23 22:59:14.264820697 +0100
--- src/testing.c 2019-12-29 20:31:46.756611485 +0100
***************
*** 21,42 ****
static void
prepare_assert_error(garray_T *gap)
{
! char buf[NUMBUFLEN];
ga_init2(gap, 1, 100);
! if (sourcing_name != NULL)
{
! ga_concat(gap, sourcing_name);
! if (sourcing_lnum > 0)
ga_concat(gap, (char_u *)" ");
}
! if (sourcing_lnum > 0)
{
! sprintf(buf, "line %ld", (long)sourcing_lnum);
ga_concat(gap, (char_u *)buf);
}
! if (sourcing_name != NULL || sourcing_lnum > 0)
ga_concat(gap, (char_u *)": ");
}
/*
--- 21,44 ----
static void
prepare_assert_error(garray_T *gap)
{
! char buf[NUMBUFLEN];
! char_u *sname = estack_sfile();
ga_init2(gap, 1, 100);
! if (sname != NULL)
{
! ga_concat(gap, sname);
! if (SOURCING_LNUM > 0)
ga_concat(gap, (char_u *)" ");
}
! if (SOURCING_LNUM > 0)
{
! sprintf(buf, "line %ld", (long)SOURCING_LNUM);
ga_concat(gap, (char_u *)buf);
}
! if (sname != NULL || SOURCING_LNUM > 0)
ga_concat(gap, (char_u *)": ");
+ vim_free(sname);
}
/*
*** ../vim-8.2.0055/src/usercmd.c 2019-12-29 13:56:28.692861883 +0100
--- src/usercmd.c 2019-12-29 16:43:13.271990339 +0100
***************
*** 191,197 ****
{
xp->xp_arg = uc->uc_compl_arg;
xp->xp_script_ctx = uc->uc_script_ctx;
! xp->xp_script_ctx.sc_lnum += sourcing_lnum;
}
# endif
// Do not search for further abbreviations
--- 191,197 ----
{
xp->xp_arg = uc->uc_compl_arg;
xp->xp_script_ctx = uc->uc_script_ctx;
! xp->xp_script_ctx.sc_lnum += SOURCING_LNUM;
}
# endif
// Do not search for further abbreviations
***************
*** 956,962 ****
cmd->uc_compl = compl;
#ifdef FEAT_EVAL
cmd->uc_script_ctx = current_sctx;
! cmd->uc_script_ctx.sc_lnum += sourcing_lnum;
cmd->uc_compl_arg = compl_arg;
#endif
cmd->uc_addr_type = addr_type;
--- 956,962 ----
cmd->uc_compl = compl;
#ifdef FEAT_EVAL
cmd->uc_script_ctx = current_sctx;
! cmd->uc_script_ctx.sc_lnum += SOURCING_LNUM;
cmd->uc_compl_arg = compl_arg;
#endif
cmd->uc_addr_type = addr_type;
*** ../vim-8.2.0055/src/userfunc.c 2019-12-25 15:03:56.526592324 +0100
--- src/userfunc.c 2019-12-29 19:44:28.321252384 +0100
***************
*** 226,231 ****
--- 226,247 ----
return OK;
}
+ static void
+ set_ufunc_name(ufunc_T *fp, char_u *name)
+ {
+ STRCPY(fp->uf_name, name);
+
+ if (name[0] == K_SPECIAL)
+ {
+ fp->uf_name_exp = alloc(STRLEN(name) + 3);
+ if (fp->uf_name_exp != NULL)
+ {
+ STRCPY(fp->uf_name_exp, "<SNR>");
+ STRCAT(fp->uf_name_exp, fp->uf_name + 3);
+ }
+ }
+ }
+
/*
* Parse a lambda expression and get a Funcref from "*arg".
* Return OK or FAIL. Returns NOTDONE for dict or {expr}.
***************
*** 309,315 ****
vim_strncpy(p + 7, s, e - s);
fp->uf_refcount = 1;
! STRCPY(fp->uf_name, name);
hash_add(&func_hashtab, UF2HIKEY(fp));
fp->uf_args = newargs;
ga_init(&fp->uf_def_args);
--- 325,331 ----
vim_strncpy(p + 7, s, e - s);
fp->uf_refcount = 1;
! set_ufunc_name(fp, name);
hash_add(&func_hashtab, UF2HIKEY(fp));
fp->uf_args = newargs;
ga_init(&fp->uf_def_args);
***************
*** 333,339 ****
fp->uf_flags = flags;
fp->uf_calls = 0;
fp->uf_script_ctx = current_sctx;
! fp->uf_script_ctx.sc_lnum += sourcing_lnum - newlines.ga_len;
pt->pt_func = fp;
pt->pt_refcount = 1;
--- 349,355 ----
fp->uf_flags = flags;
fp->uf_calls = 0;
fp->uf_script_ctx = current_sctx;
! fp->uf_script_ctx.sc_lnum += SOURCING_LNUM - newlines.ga_len;
pt->pt_func = fp;
pt->pt_refcount = 1;
***************
*** 759,766 ****
linenr_T lastline, // last line of range
dict_T *selfdict) // Dictionary for "self"
{
- char_u *save_sourcing_name;
- linenr_T save_sourcing_lnum;
sctx_T save_current_sctx;
int using_sandbox = FALSE;
funccall_T *fc;
--- 775,780 ----
***************
*** 774,780 ****
int islambda = FALSE;
char_u numbuf[NUMBUFLEN];
char_u *name;
- size_t len;
#ifdef FEAT_PROFILE
proftime_T wait_start;
proftime_T call_start;
--- 788,793 ----
***************
*** 948,956 ****
// Don't redraw while executing the function.
++RedrawingDisabled;
- save_sourcing_name = sourcing_name;
- save_sourcing_lnum = sourcing_lnum;
- sourcing_lnum = 1;
if (fp->uf_flags & FC_SANDBOX)
{
--- 961,966 ----
***************
*** 958,1022 ****
++sandbox;
}
! // need space for function name + ("function " + 3) or "[number]"
! len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name))
! + STRLEN(fp->uf_name) + 20;
! sourcing_name = alloc(len);
! if (sourcing_name != NULL)
! {
! if (save_sourcing_name != NULL
! && STRNCMP(save_sourcing_name, "function ", 9) == 0)
! sprintf((char *)sourcing_name, "%s[%d]..",
! save_sourcing_name, (int)save_sourcing_lnum);
! else
! STRCPY(sourcing_name, "function ");
! cat_func_name(sourcing_name + STRLEN(sourcing_name), fp);
!
! if (p_verbose >= 12)
! {
! ++no_wait_return;
! verbose_enter_scroll();
!
! smsg(_("calling %s"), sourcing_name);
! if (p_verbose >= 14)
! {
! char_u buf[MSG_BUF_LEN];
! char_u numbuf2[NUMBUFLEN];
! char_u *tofree;
! char_u *s;
! msg_puts("(");
! for (i = 0; i < argcount; ++i)
{
! if (i > 0)
! msg_puts(", ");
! if (argvars[i].v_type == VAR_NUMBER)
! msg_outnum((long)argvars[i].vval.v_number);
! else
{
! // Do not want errors such as E724 here.
! ++emsg_off;
! s = tv2string(&argvars[i], &tofree, numbuf2, 0);
! --emsg_off;
! if (s != NULL)
{
! if (vim_strsize(s) > MSG_BUF_CLEN)
! {
! trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
! s = buf;
! }
! msg_puts((char *)s);
! vim_free(tofree);
}
}
}
- msg_puts(")");
}
! msg_puts("\n"); // don't overwrite this either
!
! verbose_leave_scroll();
! --no_wait_return;
}
}
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
--- 968,1018 ----
++sandbox;
}
! estack_push_ufunc(ETYPE_UFUNC, fp, 1);
! if (p_verbose >= 12)
! {
! ++no_wait_return;
! verbose_enter_scroll();
!
! smsg(_("calling %s"), SOURCING_NAME);
! if (p_verbose >= 14)
! {
! char_u buf[MSG_BUF_LEN];
! char_u numbuf2[NUMBUFLEN];
! char_u *tofree;
! char_u *s;
! msg_puts("(");
! for (i = 0; i < argcount; ++i)
! {
! if (i > 0)
! msg_puts(", ");
! if (argvars[i].v_type == VAR_NUMBER)
! msg_outnum((long)argvars[i].vval.v_number);
! else
{
! // Do not want errors such as E724 here.
! ++emsg_off;
! s = tv2string(&argvars[i], &tofree, numbuf2, 0);
! --emsg_off;
! if (s != NULL)
{
! if (vim_strsize(s) > MSG_BUF_CLEN)
{
! trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
! s = buf;
}
+ msg_puts((char *)s);
+ vim_free(tofree);
}
}
}
! msg_puts(")");
}
+ msg_puts("\n"); // don't overwrite this either
+
+ verbose_leave_scroll();
+ --no_wait_return;
}
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
***************
*** 1085,1093 ****
verbose_enter_scroll();
if (aborting())
! smsg(_("%s aborted"), sourcing_name);
else if (fc->rettv->v_type == VAR_NUMBER)
! smsg(_("%s returning #%ld"), sourcing_name,
(long)fc->rettv->vval.v_number);
else
{
--- 1081,1089 ----
verbose_enter_scroll();
if (aborting())
! smsg(_("%s aborted"), SOURCING_NAME);
else if (fc->rettv->v_type == VAR_NUMBER)
! smsg(_("%s returning #%ld"), SOURCING_NAME,
(long)fc->rettv->vval.v_number);
else
{
***************
*** 1109,1115 ****
trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
s = buf;
}
! smsg(_("%s returning %s"), sourcing_name, s);
vim_free(tofree);
}
}
--- 1105,1111 ----
trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
s = buf;
}
! smsg(_("%s returning %s"), SOURCING_NAME, s);
vim_free(tofree);
}
}
***************
*** 1119,1127 ****
--no_wait_return;
}
! vim_free(sourcing_name);
! sourcing_name = save_sourcing_name;
! sourcing_lnum = save_sourcing_lnum;
current_sctx = save_current_sctx;
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
--- 1115,1121 ----
--no_wait_return;
}
! estack_pop();
current_sctx = save_current_sctx;
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
***************
*** 1130,1141 ****
if (using_sandbox)
--sandbox;
! if (p_verbose >= 12 && sourcing_name != NULL)
{
++no_wait_return;
verbose_enter_scroll();
! smsg(_("continuing in %s"), sourcing_name);
msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
--- 1124,1135 ----
if (using_sandbox)
--sandbox;
! if (p_verbose >= 12 && SOURCING_NAME != NULL)
{
++no_wait_return;
verbose_enter_scroll();
! smsg(_("continuing in %s"), SOURCING_NAME);
msg_puts("\n"); // don't overwrite this either
verbose_leave_scroll();
***************
*** 1204,1216 ****
ga_clear_strings(&(fp->uf_args));
ga_clear_strings(&(fp->uf_def_args));
ga_clear_strings(&(fp->uf_lines));
#ifdef FEAT_PROFILE
! vim_free(fp->uf_tml_count);
! fp->uf_tml_count = NULL;
! vim_free(fp->uf_tml_total);
! fp->uf_tml_total = NULL;
! vim_free(fp->uf_tml_self);
! fp->uf_tml_self = NULL;
#endif
}
--- 1198,1208 ----
ga_clear_strings(&(fp->uf_args));
ga_clear_strings(&(fp->uf_def_args));
ga_clear_strings(&(fp->uf_lines));
+ VIM_CLEAR(fp->uf_name_exp);
#ifdef FEAT_PROFILE
! VIM_CLEAR(fp->uf_tml_count);
! VIM_CLEAR(fp->uf_tml_total);
! VIM_CLEAR(fp->uf_tml_self);
#endif
}
***************
*** 1736,1746 ****
if (indent)
msg_puts(" ");
msg_puts("function ");
! if (fp->uf_name[0] == K_SPECIAL)
! {
! msg_puts_attr("<SNR>", HL_ATTR(HLF_8));
! msg_puts((char *)fp->uf_name + 3);
! }
else
msg_puts((char *)fp->uf_name);
msg_putchar('(');
--- 1728,1735 ----
if (indent)
msg_puts(" ");
msg_puts("function ");
! if (fp->uf_name_exp != NULL)
! msg_puts((char *)fp->uf_name_exp);
else
msg_puts((char *)fp->uf_name);
msg_putchar('(');
***************
*** 2308,2314 ****
}
// Save the starting line number.
! sourcing_lnum_top = sourcing_lnum;
indent = 2;
nesting = 0;
--- 2297,2303 ----
}
// Save the starting line number.
! sourcing_lnum_top = SOURCING_LNUM;
indent = 2;
nesting = 0;
***************
*** 2351,2360 ****
goto erret;
}
! // Detect line continuation: sourcing_lnum increased more than one.
sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
! if (sourcing_lnum < sourcing_lnum_off)
! sourcing_lnum_off -= sourcing_lnum;
else
sourcing_lnum_off = 0;
--- 2340,2349 ----
goto erret;
}
! // Detect line continuation: SOURCING_LNUM increased more than one.
sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
! if (SOURCING_LNUM < sourcing_lnum_off)
! sourcing_lnum_off -= SOURCING_LNUM;
else
sourcing_lnum_off = 0;
***************
*** 2631,2646 ****
// Check that the autoload name matches the script name.
j = FAIL;
! if (sourcing_name != NULL)
{
scriptname = autoload_name(name);
if (scriptname != NULL)
{
p = vim_strchr(scriptname, '/');
plen = (int)STRLEN(p);
! slen = (int)STRLEN(sourcing_name);
if (slen > plen && fnamecmp(p,
! sourcing_name + slen - plen) == 0)
j = OK;
vim_free(scriptname);
}
--- 2620,2635 ----
// Check that the autoload name matches the script name.
j = FAIL;
! if (SOURCING_NAME != NULL)
{
scriptname = autoload_name(name);
if (scriptname != NULL)
{
p = vim_strchr(scriptname, '/');
plen = (int)STRLEN(p);
! slen = (int)STRLEN(SOURCING_NAME);
if (slen > plen && fnamecmp(p,
! SOURCING_NAME + slen - plen) == 0)
j = OK;
vim_free(scriptname);
}
***************
*** 2685,2691 ****
}
// insert the new function in the function list
! STRCPY(fp->uf_name, name);
if (overwrite)
{
hi = hash_find(&func_hashtab, name);
--- 2674,2680 ----
}
// insert the new function in the function list
! set_ufunc_name(fp, name);
if (overwrite)
{
hi = hash_find(&func_hashtab, name);
***************
*** 3353,3359 ****
if (fcp->dbg_tick != debug_tick)
{
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
! sourcing_lnum);
fcp->dbg_tick = debug_tick;
}
#ifdef FEAT_PROFILE
--- 3342,3348 ----
if (fcp->dbg_tick != debug_tick)
{
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
! SOURCING_LNUM);
fcp->dbg_tick = debug_tick;
}
#ifdef FEAT_PROFILE
***************
*** 3376,3382 ****
else
{
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
! sourcing_lnum = fcp->linenr;
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
func_line_start(cookie);
--- 3365,3371 ----
else
{
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
! SOURCING_LNUM = fcp->linenr;
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
func_line_start(cookie);
***************
*** 3385,3396 ****
}
// Did we encounter a breakpoint?
! if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum)
{
! dbg_breakpoint(fp->uf_name, sourcing_lnum);
// Find next breakpoint.
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
! sourcing_lnum);
fcp->dbg_tick = debug_tick;
}
--- 3374,3385 ----
}
// Did we encounter a breakpoint?
! if (fcp->breakpoint != 0 && fcp->breakpoint <= SOURCING_LNUM)
{
! dbg_breakpoint(fp->uf_name, SOURCING_LNUM);
// Find next breakpoint.
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
! SOURCING_LNUM);
fcp->dbg_tick = debug_tick;
}
*** ../vim-8.2.0055/src/kword_test.c 2019-12-04 21:41:40.000000000 +0100
--- src/kword_test.c 2019-12-29 16:50:21.846266344 +0100
***************
*** 76,81 ****
--- 76,82 ----
int
main(void)
{
+ estack_init();
test_isword_funcs_utf8();
return 0;
}
*** ../vim-8.2.0055/src/testdir/test_debugger.vim 2019-08-07 22:51:41.000000000 +0200
--- src/testdir/test_debugger.vim 2019-12-29 21:00:41.864006715 +0100
***************
*** 14,20 ****
" Verify the expected output
let lnum = 20 - len(a:1)
for l in a:1
! call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))})
let lnum += 1
endfor
endif
--- 14,20 ----
" Verify the expected output
let lnum = 20 - len(a:1)
for l in a:1
! call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, 200)
let lnum += 1
endfor
endif
*** ../vim-8.2.0055/src/version.c 2019-12-29 15:19:00.470760367 +0100
--- src/version.c 2019-12-29 22:58:51.211858220 +0100
***************
*** 744,745 ****
--- 744,747 ----
{ /* Add new patch number below this line */
+ /**/
+ 56,
/**/
--
ARTHUR: Shut up! Will you shut up!
DENNIS: Ah, now we see the violence inherent in the system.
ARTHUR: Shut up!
DENNIS: Oh! Come and see the violence inherent in the system!
HELP! HELP! I'm being repressed!
The Quest for the Holy Grail (Monty Python)
/// Bram Moolenaar -- Br...@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 ///