mirror of
https://github.com/zoriya/vim.git
synced 2025-12-19 21:55:18 +00:00
patch 8.2.0056: execution stack is incomplete and inefficient
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.
This commit is contained in:
@@ -218,7 +218,7 @@ static AutoPat *last_autopat[NUM_EVENTS] =
|
|||||||
/*
|
/*
|
||||||
* struct used to keep status while executing autocommands for an event.
|
* struct used to keep status while executing autocommands for an event.
|
||||||
*/
|
*/
|
||||||
typedef struct AutoPatCmd
|
struct AutoPatCmd_S
|
||||||
{
|
{
|
||||||
AutoPat *curpat; // next AutoPat to examine
|
AutoPat *curpat; // next AutoPat to examine
|
||||||
AutoCmd *nextcmd; // next AutoCmd to execute
|
AutoCmd *nextcmd; // next AutoCmd to execute
|
||||||
@@ -229,8 +229,8 @@ typedef struct AutoPatCmd
|
|||||||
event_T event; // current event
|
event_T event; // current event
|
||||||
int arg_bufnr; // Initially equal to <abuf>, set to zero when
|
int arg_bufnr; // Initially equal to <abuf>, set to zero when
|
||||||
// buf is deleted.
|
// buf is deleted.
|
||||||
struct AutoPatCmd *next; // chain of active apc-s for auto-invalidation
|
AutoPatCmd *next; // chain of active apc-s for auto-invalidation
|
||||||
} AutoPatCmd;
|
};
|
||||||
|
|
||||||
static AutoPatCmd *active_apc_list = NULL; // stack of active autocommands
|
static AutoPatCmd *active_apc_list = NULL; // stack of active autocommands
|
||||||
|
|
||||||
@@ -1242,7 +1242,7 @@ do_autocmd_event(
|
|||||||
ac->cmd = vim_strsave(cmd);
|
ac->cmd = vim_strsave(cmd);
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
ac->script_ctx = current_sctx;
|
ac->script_ctx = current_sctx;
|
||||||
ac->script_ctx.sc_lnum += sourcing_lnum;
|
ac->script_ctx.sc_lnum += SOURCING_LNUM;
|
||||||
#endif
|
#endif
|
||||||
if (ac->cmd == NULL)
|
if (ac->cmd == NULL)
|
||||||
{
|
{
|
||||||
@@ -1805,8 +1805,6 @@ apply_autocmds_group(
|
|||||||
int save_changed;
|
int save_changed;
|
||||||
buf_T *old_curbuf;
|
buf_T *old_curbuf;
|
||||||
int retval = FALSE;
|
int retval = FALSE;
|
||||||
char_u *save_sourcing_name;
|
|
||||||
linenr_T save_sourcing_lnum;
|
|
||||||
char_u *save_autocmd_fname;
|
char_u *save_autocmd_fname;
|
||||||
int save_autocmd_fname_full;
|
int save_autocmd_fname_full;
|
||||||
int save_autocmd_bufnr;
|
int save_autocmd_bufnr;
|
||||||
@@ -2020,10 +2018,9 @@ apply_autocmds_group(
|
|||||||
|
|
||||||
// Don't redraw while doing autocommands.
|
// Don't redraw while doing autocommands.
|
||||||
++RedrawingDisabled;
|
++RedrawingDisabled;
|
||||||
save_sourcing_name = sourcing_name;
|
|
||||||
sourcing_name = NULL; // don't free this one
|
// name and lnum are filled in later
|
||||||
save_sourcing_lnum = sourcing_lnum;
|
estack_push(ETYPE_AUCMD, NULL, 0);
|
||||||
sourcing_lnum = 0; // no line number here
|
|
||||||
|
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
save_current_sctx = current_sctx;
|
save_current_sctx = current_sctx;
|
||||||
@@ -2126,9 +2123,8 @@ apply_autocmds_group(
|
|||||||
autocmd_busy = save_autocmd_busy;
|
autocmd_busy = save_autocmd_busy;
|
||||||
filechangeshell_busy = FALSE;
|
filechangeshell_busy = FALSE;
|
||||||
autocmd_nested = save_autocmd_nested;
|
autocmd_nested = save_autocmd_nested;
|
||||||
vim_free(sourcing_name);
|
vim_free(SOURCING_NAME);
|
||||||
sourcing_name = save_sourcing_name;
|
estack_pop();
|
||||||
sourcing_lnum = save_sourcing_lnum;
|
|
||||||
vim_free(autocmd_fname);
|
vim_free(autocmd_fname);
|
||||||
autocmd_fname = save_autocmd_fname;
|
autocmd_fname = save_autocmd_fname;
|
||||||
autocmd_fname_full = save_autocmd_fname_full;
|
autocmd_fname_full = save_autocmd_fname_full;
|
||||||
@@ -2256,8 +2252,9 @@ auto_next_pat(
|
|||||||
AutoCmd *cp;
|
AutoCmd *cp;
|
||||||
char_u *name;
|
char_u *name;
|
||||||
char *s;
|
char *s;
|
||||||
|
char_u **sourcing_namep = &SOURCING_NAME;
|
||||||
|
|
||||||
VIM_CLEAR(sourcing_name);
|
VIM_CLEAR(*sourcing_namep);
|
||||||
|
|
||||||
for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
|
for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next)
|
||||||
{
|
{
|
||||||
@@ -2277,16 +2274,16 @@ auto_next_pat(
|
|||||||
{
|
{
|
||||||
name = event_nr2name(apc->event);
|
name = event_nr2name(apc->event);
|
||||||
s = _("%s Autocommands for \"%s\"");
|
s = _("%s Autocommands for \"%s\"");
|
||||||
sourcing_name = alloc(STRLEN(s)
|
*sourcing_namep = alloc(STRLEN(s)
|
||||||
+ STRLEN(name) + ap->patlen + 1);
|
+ STRLEN(name) + ap->patlen + 1);
|
||||||
if (sourcing_name != NULL)
|
if (*sourcing_namep != NULL)
|
||||||
{
|
{
|
||||||
sprintf((char *)sourcing_name, s,
|
sprintf((char *)*sourcing_namep, s,
|
||||||
(char *)name, (char *)ap->pat);
|
(char *)name, (char *)ap->pat);
|
||||||
if (p_verbose >= 8)
|
if (p_verbose >= 8)
|
||||||
{
|
{
|
||||||
verbose_enter();
|
verbose_enter();
|
||||||
smsg(_("Executing %s"), sourcing_name);
|
smsg(_("Executing %s"), *sourcing_namep);
|
||||||
verbose_leave();
|
verbose_leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/buffer.c
14
src/buffer.c
@@ -5279,8 +5279,6 @@ chk_modeline(
|
|||||||
int vers;
|
int vers;
|
||||||
int end;
|
int end;
|
||||||
int retval = OK;
|
int retval = OK;
|
||||||
char_u *save_sourcing_name;
|
|
||||||
linenr_T save_sourcing_lnum;
|
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
sctx_T save_current_sctx;
|
sctx_T save_current_sctx;
|
||||||
#endif
|
#endif
|
||||||
@@ -5325,10 +5323,8 @@ chk_modeline(
|
|||||||
if (linecopy == NULL)
|
if (linecopy == NULL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
|
|
||||||
save_sourcing_lnum = sourcing_lnum;
|
// prepare for emsg()
|
||||||
save_sourcing_name = sourcing_name;
|
estack_push(ETYPE_MODELINE, (char_u *)"modelines", lnum);
|
||||||
sourcing_lnum = lnum; // prepare for emsg()
|
|
||||||
sourcing_name = (char_u *)"modelines";
|
|
||||||
|
|
||||||
end = FALSE;
|
end = FALSE;
|
||||||
while (end == FALSE)
|
while (end == FALSE)
|
||||||
@@ -5371,7 +5367,7 @@ chk_modeline(
|
|||||||
save_current_sctx = current_sctx;
|
save_current_sctx = current_sctx;
|
||||||
current_sctx.sc_sid = SID_MODELINE;
|
current_sctx.sc_sid = SID_MODELINE;
|
||||||
current_sctx.sc_seq = 0;
|
current_sctx.sc_seq = 0;
|
||||||
current_sctx.sc_lnum = 0;
|
current_sctx.sc_lnum = lnum;
|
||||||
current_sctx.sc_version = 1;
|
current_sctx.sc_version = 1;
|
||||||
#endif
|
#endif
|
||||||
// Make sure no risky things are executed as a side effect.
|
// Make sure no risky things are executed as a side effect.
|
||||||
@@ -5389,9 +5385,7 @@ chk_modeline(
|
|||||||
s = e + 1; // advance to next part
|
s = e + 1; // advance to next part
|
||||||
}
|
}
|
||||||
|
|
||||||
sourcing_lnum = save_sourcing_lnum;
|
estack_pop();
|
||||||
sourcing_name = save_sourcing_name;
|
|
||||||
|
|
||||||
vim_free(linecopy);
|
vim_free(linecopy);
|
||||||
}
|
}
|
||||||
return retval;
|
return retval;
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ do_debug(char_u *cmd)
|
|||||||
int n;
|
int n;
|
||||||
char_u *cmdline = NULL;
|
char_u *cmdline = NULL;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
|
char_u *sname;
|
||||||
char *tail = NULL;
|
char *tail = NULL;
|
||||||
static int last_cmd = 0;
|
static int last_cmd = 0;
|
||||||
#define CMD_CONT 1
|
#define CMD_CONT 1
|
||||||
@@ -104,10 +105,12 @@ do_debug(char_u *cmd)
|
|||||||
vim_free(debug_newval);
|
vim_free(debug_newval);
|
||||||
debug_newval = NULL;
|
debug_newval = NULL;
|
||||||
}
|
}
|
||||||
if (sourcing_name != NULL)
|
sname = estack_sfile();
|
||||||
msg((char *)sourcing_name);
|
if (sname != NULL)
|
||||||
if (sourcing_lnum != 0)
|
msg((char *)sname);
|
||||||
smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd);
|
vim_free(sname);
|
||||||
|
if (SOURCING_LNUM != 0)
|
||||||
|
smsg(_("line %ld: %s"), SOURCING_LNUM, cmd);
|
||||||
else
|
else
|
||||||
smsg(_("cmd: %s"), cmd);
|
smsg(_("cmd: %s"), cmd);
|
||||||
|
|
||||||
@@ -300,14 +303,14 @@ do_debug(char_u *cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_maxbacktrace_level(void)
|
get_maxbacktrace_level(char_u *sname)
|
||||||
{
|
{
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
int maxbacktrace = 0;
|
int maxbacktrace = 0;
|
||||||
|
|
||||||
if (sourcing_name != NULL)
|
if (sname != NULL)
|
||||||
{
|
{
|
||||||
p = (char *)sourcing_name;
|
p = (char *)sname;
|
||||||
while ((q = strstr(p, "..")) != NULL)
|
while ((q = strstr(p, "..")) != NULL)
|
||||||
{
|
{
|
||||||
p = q + 2;
|
p = q + 2;
|
||||||
@@ -341,27 +344,32 @@ do_checkbacktracelevel(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int max = get_maxbacktrace_level();
|
char_u *sname = estack_sfile();
|
||||||
|
int max = get_maxbacktrace_level(sname);
|
||||||
|
|
||||||
if (debug_backtrace_level > max)
|
if (debug_backtrace_level > max)
|
||||||
{
|
{
|
||||||
debug_backtrace_level = max;
|
debug_backtrace_level = max;
|
||||||
smsg(_("frame at highest level: %d"), max);
|
smsg(_("frame at highest level: %d"), max);
|
||||||
}
|
}
|
||||||
|
vim_free(sname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_showbacktrace(char_u *cmd)
|
do_showbacktrace(char_u *cmd)
|
||||||
{
|
{
|
||||||
|
char_u *sname;
|
||||||
char *cur;
|
char *cur;
|
||||||
char *next;
|
char *next;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int max = get_maxbacktrace_level();
|
int max;
|
||||||
|
|
||||||
if (sourcing_name != NULL)
|
sname = estack_sfile();
|
||||||
|
max = get_maxbacktrace_level(sname);
|
||||||
|
if (sname != NULL)
|
||||||
{
|
{
|
||||||
cur = (char *)sourcing_name;
|
cur = (char *)sname;
|
||||||
while (!got_int)
|
while (!got_int)
|
||||||
{
|
{
|
||||||
next = strstr(cur, "..");
|
next = strstr(cur, "..");
|
||||||
@@ -377,9 +385,11 @@ do_showbacktrace(char_u *cmd)
|
|||||||
*next = '.';
|
*next = '.';
|
||||||
cur = next + 2;
|
cur = next + 2;
|
||||||
}
|
}
|
||||||
|
vim_free(sname);
|
||||||
}
|
}
|
||||||
if (sourcing_lnum != 0)
|
|
||||||
smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd);
|
if (SOURCING_LNUM != 0)
|
||||||
|
smsg(_("line %ld: %s"), (long)SOURCING_LNUM, cmd);
|
||||||
else
|
else
|
||||||
smsg(_("cmd: %s"), cmd);
|
smsg(_("cmd: %s"), cmd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -703,7 +703,7 @@ do_cmdline(
|
|||||||
}
|
}
|
||||||
else if (getline_equal(fgetline, cookie, getsourceline))
|
else if (getline_equal(fgetline, cookie, getsourceline))
|
||||||
{
|
{
|
||||||
fname = sourcing_name;
|
fname = SOURCING_NAME;
|
||||||
breakpoint = source_breakpoint(real_cookie);
|
breakpoint = source_breakpoint(real_cookie);
|
||||||
dbg_tick = source_dbg_tick(real_cookie);
|
dbg_tick = source_dbg_tick(real_cookie);
|
||||||
}
|
}
|
||||||
@@ -819,22 +819,22 @@ do_cmdline(
|
|||||||
{
|
{
|
||||||
*breakpoint = dbg_find_breakpoint(
|
*breakpoint = dbg_find_breakpoint(
|
||||||
getline_equal(fgetline, cookie, getsourceline),
|
getline_equal(fgetline, cookie, getsourceline),
|
||||||
fname, sourcing_lnum);
|
fname, SOURCING_LNUM);
|
||||||
*dbg_tick = debug_tick;
|
*dbg_tick = debug_tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
next_cmdline = ((wcmd_T *)(lines_ga.ga_data))[current_line].line;
|
next_cmdline = ((wcmd_T *)(lines_ga.ga_data))[current_line].line;
|
||||||
sourcing_lnum = ((wcmd_T *)(lines_ga.ga_data))[current_line].lnum;
|
SOURCING_LNUM = ((wcmd_T *)(lines_ga.ga_data))[current_line].lnum;
|
||||||
|
|
||||||
// Did we encounter a breakpoint?
|
// Did we encounter a breakpoint?
|
||||||
if (breakpoint != NULL && *breakpoint != 0
|
if (breakpoint != NULL && *breakpoint != 0
|
||||||
&& *breakpoint <= sourcing_lnum)
|
&& *breakpoint <= SOURCING_LNUM)
|
||||||
{
|
{
|
||||||
dbg_breakpoint(fname, sourcing_lnum);
|
dbg_breakpoint(fname, SOURCING_LNUM);
|
||||||
// Find next breakpoint.
|
// Find next breakpoint.
|
||||||
*breakpoint = dbg_find_breakpoint(
|
*breakpoint = dbg_find_breakpoint(
|
||||||
getline_equal(fgetline, cookie, getsourceline),
|
getline_equal(fgetline, cookie, getsourceline),
|
||||||
fname, sourcing_lnum);
|
fname, SOURCING_LNUM);
|
||||||
*dbg_tick = debug_tick;
|
*dbg_tick = debug_tick;
|
||||||
}
|
}
|
||||||
# ifdef FEAT_PROFILE
|
# ifdef FEAT_PROFILE
|
||||||
@@ -963,8 +963,8 @@ do_cmdline(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_verbose >= 15 && sourcing_name != NULL)
|
if (p_verbose >= 15 && SOURCING_NAME != NULL)
|
||||||
msg_verbose_cmd(sourcing_lnum, cmdline_copy);
|
msg_verbose_cmd(SOURCING_LNUM, cmdline_copy);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2. Execute one '|' separated command.
|
* 2. Execute one '|' separated command.
|
||||||
@@ -1081,7 +1081,7 @@ do_cmdline(
|
|||||||
// Check for the next breakpoint after a watchexpression
|
// Check for the next breakpoint after a watchexpression
|
||||||
if (breakpoint != NULL && has_watchexpr())
|
if (breakpoint != NULL && has_watchexpr())
|
||||||
{
|
{
|
||||||
*breakpoint = dbg_find_breakpoint(FALSE, fname, sourcing_lnum);
|
*breakpoint = dbg_find_breakpoint(FALSE, fname, SOURCING_LNUM);
|
||||||
*dbg_tick = debug_tick;
|
*dbg_tick = debug_tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1092,7 +1092,7 @@ do_cmdline(
|
|||||||
{
|
{
|
||||||
if (lines_ga.ga_len > 0)
|
if (lines_ga.ga_len > 0)
|
||||||
{
|
{
|
||||||
sourcing_lnum =
|
SOURCING_LNUM =
|
||||||
((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
|
((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
|
||||||
free_cmdlines(&lines_ga);
|
free_cmdlines(&lines_ga);
|
||||||
}
|
}
|
||||||
@@ -1234,8 +1234,6 @@ do_cmdline(
|
|||||||
if (did_throw)
|
if (did_throw)
|
||||||
{
|
{
|
||||||
void *p = NULL;
|
void *p = NULL;
|
||||||
char_u *saved_sourcing_name;
|
|
||||||
int saved_sourcing_lnum;
|
|
||||||
struct msglist *messages = NULL, *next;
|
struct msglist *messages = NULL, *next;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1260,10 +1258,8 @@ do_cmdline(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
saved_sourcing_name = sourcing_name;
|
estack_push(ETYPE_EXCEPT, current_exception->throw_name,
|
||||||
saved_sourcing_lnum = sourcing_lnum;
|
current_exception->throw_lnum);
|
||||||
sourcing_name = current_exception->throw_name;
|
|
||||||
sourcing_lnum = current_exception->throw_lnum;
|
|
||||||
current_exception->throw_name = NULL;
|
current_exception->throw_name = NULL;
|
||||||
|
|
||||||
discard_current_exception(); // uses IObuff if 'verbose'
|
discard_current_exception(); // uses IObuff if 'verbose'
|
||||||
@@ -1287,9 +1283,8 @@ do_cmdline(
|
|||||||
emsg(p);
|
emsg(p);
|
||||||
vim_free(p);
|
vim_free(p);
|
||||||
}
|
}
|
||||||
vim_free(sourcing_name);
|
vim_free(SOURCING_NAME);
|
||||||
sourcing_name = saved_sourcing_name;
|
estack_pop();
|
||||||
sourcing_lnum = saved_sourcing_lnum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1428,7 +1423,7 @@ get_loop_line(int c, void *cookie, int indent, int do_concat)
|
|||||||
KeyTyped = FALSE;
|
KeyTyped = FALSE;
|
||||||
++cp->current_line;
|
++cp->current_line;
|
||||||
wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line;
|
wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line;
|
||||||
sourcing_lnum = wp->lnum;
|
SOURCING_LNUM = wp->lnum;
|
||||||
return vim_strsave(wp->line);
|
return vim_strsave(wp->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1441,7 +1436,7 @@ store_loop_line(garray_T *gap, char_u *line)
|
|||||||
if (ga_grow(gap, 1) == FAIL)
|
if (ga_grow(gap, 1) == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
((wcmd_T *)(gap->ga_data))[gap->ga_len].line = vim_strsave(line);
|
((wcmd_T *)(gap->ga_data))[gap->ga_len].line = vim_strsave(line);
|
||||||
((wcmd_T *)(gap->ga_data))[gap->ga_len].lnum = sourcing_lnum;
|
((wcmd_T *)(gap->ga_data))[gap->ga_len].lnum = SOURCING_LNUM;
|
||||||
++gap->ga_len;
|
++gap->ga_len;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -8171,33 +8166,34 @@ eval_vars(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SPEC_SFILE: // file name for ":so" command
|
case SPEC_SFILE: // file name for ":so" command
|
||||||
result = sourcing_name;
|
result = estack_sfile();
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
{
|
{
|
||||||
*errormsg = _("E498: no :source file name to substitute for \"<sfile>\"");
|
*errormsg = _("E498: no :source file name to substitute for \"<sfile>\"");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
resultbuf = result; // remember allocated string
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPEC_SLNUM: // line in file for ":so" command
|
case SPEC_SLNUM: // line in file for ":so" command
|
||||||
if (sourcing_name == NULL || sourcing_lnum == 0)
|
if (SOURCING_NAME == NULL || SOURCING_LNUM == 0)
|
||||||
{
|
{
|
||||||
*errormsg = _("E842: no line number to use for \"<slnum>\"");
|
*errormsg = _("E842: no line number to use for \"<slnum>\"");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sprintf((char *)strbuf, "%ld", (long)sourcing_lnum);
|
sprintf((char *)strbuf, "%ld", SOURCING_LNUM);
|
||||||
result = strbuf;
|
result = strbuf;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
case SPEC_SFLNUM: // line in script file
|
case SPEC_SFLNUM: // line in script file
|
||||||
if (current_sctx.sc_lnum + sourcing_lnum == 0)
|
if (current_sctx.sc_lnum + SOURCING_LNUM == 0)
|
||||||
{
|
{
|
||||||
*errormsg = _("E961: no line number to use for \"<sflnum>\"");
|
*errormsg = _("E961: no line number to use for \"<sflnum>\"");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
sprintf((char *)strbuf, "%ld",
|
sprintf((char *)strbuf, "%ld",
|
||||||
(long)(current_sctx.sc_lnum + sourcing_lnum));
|
(long)(current_sctx.sc_lnum + SOURCING_LNUM));
|
||||||
result = strbuf;
|
result = strbuf;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -534,15 +534,16 @@ throw_exception(void *value, except_type_T type, char_u *cmdname)
|
|||||||
goto nomem;
|
goto nomem;
|
||||||
|
|
||||||
excp->type = type;
|
excp->type = type;
|
||||||
excp->throw_name = vim_strsave(sourcing_name == NULL
|
excp->throw_name = estack_sfile();
|
||||||
? (char_u *)"" : sourcing_name);
|
if (excp->throw_name == NULL)
|
||||||
|
excp->throw_name = vim_strsave((char_u *)"");
|
||||||
if (excp->throw_name == NULL)
|
if (excp->throw_name == NULL)
|
||||||
{
|
{
|
||||||
if (should_free)
|
if (should_free)
|
||||||
vim_free(excp->value);
|
vim_free(excp->value);
|
||||||
goto nomem;
|
goto nomem;
|
||||||
}
|
}
|
||||||
excp->throw_lnum = sourcing_lnum;
|
excp->throw_lnum = SOURCING_LNUM;
|
||||||
|
|
||||||
if (p_verbose >= 13 || debug_break_level > 0)
|
if (p_verbose >= 13 || debug_break_level > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -266,8 +266,15 @@ EXTERN int lines_left INIT(= -1); // lines left for listing
|
|||||||
EXTERN int msg_no_more INIT(= FALSE); // don't use more prompt, truncate
|
EXTERN int msg_no_more INIT(= FALSE); // don't use more prompt, truncate
|
||||||
// messages
|
// 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
|
* 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
|
#ifdef FEAT_EVAL
|
||||||
EXTERN int ex_nesting_level INIT(= 0); // nesting level
|
EXTERN int ex_nesting_level INIT(= 0); // nesting level
|
||||||
|
|||||||
@@ -748,7 +748,7 @@ do_highlight(
|
|||||||
if (to_id > 0 && !forceit && !init
|
if (to_id > 0 && !forceit && !init
|
||||||
&& hl_has_settings(from_id - 1, dodefault))
|
&& hl_has_settings(from_id - 1, dodefault))
|
||||||
{
|
{
|
||||||
if (sourcing_name == NULL && !dodefault)
|
if (SOURCING_NAME == NULL && !dodefault)
|
||||||
emsg(_("E414: group has settings, highlight link ignored"));
|
emsg(_("E414: group has settings, highlight link ignored"));
|
||||||
}
|
}
|
||||||
else if (HL_TABLE()[from_id - 1].sg_link != to_id
|
else if (HL_TABLE()[from_id - 1].sg_link != to_id
|
||||||
@@ -763,7 +763,7 @@ do_highlight(
|
|||||||
HL_TABLE()[from_id - 1].sg_link = to_id;
|
HL_TABLE()[from_id - 1].sg_link = to_id;
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx;
|
HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx;
|
||||||
HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += sourcing_lnum;
|
HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||||
#endif
|
#endif
|
||||||
HL_TABLE()[from_id - 1].sg_cleared = FALSE;
|
HL_TABLE()[from_id - 1].sg_cleared = FALSE;
|
||||||
redraw_all_later(SOME_VALID);
|
redraw_all_later(SOME_VALID);
|
||||||
@@ -1518,7 +1518,7 @@ do_highlight(
|
|||||||
set_hl_attr(idx);
|
set_hl_attr(idx);
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
HL_TABLE()[idx].sg_script_ctx = current_sctx;
|
HL_TABLE()[idx].sg_script_ctx = current_sctx;
|
||||||
HL_TABLE()[idx].sg_script_ctx.sc_lnum += sourcing_lnum;
|
HL_TABLE()[idx].sg_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ test_isword_funcs_utf8(void)
|
|||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
|
estack_init();
|
||||||
test_isword_funcs_utf8();
|
test_isword_funcs_utf8();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/main.c
20
src/main.c
@@ -911,6 +911,7 @@ vim_main2(void)
|
|||||||
void
|
void
|
||||||
common_init(mparm_T *paramp)
|
common_init(mparm_T *paramp)
|
||||||
{
|
{
|
||||||
|
estack_init();
|
||||||
cmdline_init();
|
cmdline_init();
|
||||||
|
|
||||||
(void)mb_init(); // init mb_bytelen_tab[] to ones
|
(void)mb_init(); // init mb_bytelen_tab[] to ones
|
||||||
@@ -3089,13 +3090,13 @@ exe_pre_commands(mparm_T *parmp)
|
|||||||
if (cnt > 0)
|
if (cnt > 0)
|
||||||
{
|
{
|
||||||
curwin->w_cursor.lnum = 0; // just in case..
|
curwin->w_cursor.lnum = 0; // just in case..
|
||||||
sourcing_name = (char_u *)_("pre-vimrc command line");
|
estack_push(ETYPE_ARGS, (char_u *)_("pre-vimrc command line"), 0);
|
||||||
# ifdef FEAT_EVAL
|
# ifdef FEAT_EVAL
|
||||||
current_sctx.sc_sid = SID_CMDARG;
|
current_sctx.sc_sid = SID_CMDARG;
|
||||||
# endif
|
# endif
|
||||||
for (i = 0; i < cnt; ++i)
|
for (i = 0; i < cnt; ++i)
|
||||||
do_cmdline_cmd(cmds[i]);
|
do_cmdline_cmd(cmds[i]);
|
||||||
sourcing_name = NULL;
|
estack_pop();
|
||||||
# ifdef FEAT_EVAL
|
# ifdef FEAT_EVAL
|
||||||
current_sctx.sc_sid = 0;
|
current_sctx.sc_sid = 0;
|
||||||
# endif
|
# endif
|
||||||
@@ -3119,7 +3120,7 @@ exe_commands(mparm_T *parmp)
|
|||||||
msg_scroll = TRUE;
|
msg_scroll = TRUE;
|
||||||
if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
|
if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1)
|
||||||
curwin->w_cursor.lnum = 0;
|
curwin->w_cursor.lnum = 0;
|
||||||
sourcing_name = (char_u *)"command line";
|
estack_push(ETYPE_ARGS, (char_u *)"command line", 0);
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
current_sctx.sc_sid = SID_CARG;
|
current_sctx.sc_sid = SID_CARG;
|
||||||
current_sctx.sc_seq = 0;
|
current_sctx.sc_seq = 0;
|
||||||
@@ -3130,7 +3131,7 @@ exe_commands(mparm_T *parmp)
|
|||||||
if (parmp->cmds_tofree[i])
|
if (parmp->cmds_tofree[i])
|
||||||
vim_free(parmp->commands[i]);
|
vim_free(parmp->commands[i]);
|
||||||
}
|
}
|
||||||
sourcing_name = NULL;
|
estack_pop();
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
current_sctx.sc_sid = 0;
|
current_sctx.sc_sid = 0;
|
||||||
#endif
|
#endif
|
||||||
@@ -3336,8 +3337,6 @@ process_env(
|
|||||||
int is_viminit) // when TRUE, called for VIMINIT
|
int is_viminit) // when TRUE, called for VIMINIT
|
||||||
{
|
{
|
||||||
char_u *initstr;
|
char_u *initstr;
|
||||||
char_u *save_sourcing_name;
|
|
||||||
linenr_T save_sourcing_lnum;
|
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
sctx_T save_current_sctx;
|
sctx_T save_current_sctx;
|
||||||
#endif
|
#endif
|
||||||
@@ -3346,10 +3345,7 @@ process_env(
|
|||||||
{
|
{
|
||||||
if (is_viminit)
|
if (is_viminit)
|
||||||
vimrc_found(NULL, NULL);
|
vimrc_found(NULL, NULL);
|
||||||
save_sourcing_name = sourcing_name;
|
estack_push(ETYPE_ENV, env, 0);
|
||||||
save_sourcing_lnum = sourcing_lnum;
|
|
||||||
sourcing_name = env;
|
|
||||||
sourcing_lnum = 0;
|
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
save_current_sctx = current_sctx;
|
save_current_sctx = current_sctx;
|
||||||
current_sctx.sc_sid = SID_ENV;
|
current_sctx.sc_sid = SID_ENV;
|
||||||
@@ -3358,8 +3354,8 @@ process_env(
|
|||||||
current_sctx.sc_version = 1;
|
current_sctx.sc_version = 1;
|
||||||
#endif
|
#endif
|
||||||
do_cmdline_cmd(initstr);
|
do_cmdline_cmd(initstr);
|
||||||
sourcing_name = save_sourcing_name;
|
|
||||||
sourcing_lnum = save_sourcing_lnum;
|
estack_pop();
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
current_sctx = save_current_sctx;
|
current_sctx = save_current_sctx;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
11
src/map.c
11
src/map.c
@@ -697,7 +697,7 @@ do_map(
|
|||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
mp->m_expr = expr;
|
mp->m_expr = expr;
|
||||||
mp->m_script_ctx = current_sctx;
|
mp->m_script_ctx = current_sctx;
|
||||||
mp->m_script_ctx.sc_lnum += sourcing_lnum;
|
mp->m_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||||
#endif
|
#endif
|
||||||
did_it = TRUE;
|
did_it = TRUE;
|
||||||
}
|
}
|
||||||
@@ -796,7 +796,7 @@ do_map(
|
|||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
mp->m_expr = expr;
|
mp->m_expr = expr;
|
||||||
mp->m_script_ctx = current_sctx;
|
mp->m_script_ctx = current_sctx;
|
||||||
mp->m_script_ctx.sc_lnum += sourcing_lnum;
|
mp->m_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// add the new entry in front of the abbrlist or maphash[] list
|
// add the new entry in front of the abbrlist or maphash[] list
|
||||||
@@ -1915,14 +1915,13 @@ check_map_keycodes(void)
|
|||||||
char_u *p;
|
char_u *p;
|
||||||
int i;
|
int i;
|
||||||
char_u buf[3];
|
char_u buf[3];
|
||||||
char_u *save_name;
|
|
||||||
int abbr;
|
int abbr;
|
||||||
int hash;
|
int hash;
|
||||||
buf_T *bp;
|
buf_T *bp;
|
||||||
|
|
||||||
validate_maphash();
|
validate_maphash();
|
||||||
save_name = sourcing_name;
|
// avoids giving error messages
|
||||||
sourcing_name = (char_u *)"mappings"; // avoids giving error messages
|
estack_push(ETYPE_INTERNAL, (char_u *)"mappings", 0);
|
||||||
|
|
||||||
// Do this once for each buffer, and then once for global
|
// Do this once for each buffer, and then once for global
|
||||||
// mappings/abbreviations with bp == NULL
|
// mappings/abbreviations with bp == NULL
|
||||||
@@ -1979,7 +1978,7 @@ check_map_keycodes(void)
|
|||||||
if (bp == NULL)
|
if (bp == NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sourcing_name = save_name;
|
estack_pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||||
|
|||||||
@@ -434,15 +434,15 @@ reset_last_sourcing(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE if "sourcing_name" differs from "last_sourcing_name".
|
* Return TRUE if "SOURCING_NAME" differs from "last_sourcing_name".
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
other_sourcing_name(void)
|
other_sourcing_name(void)
|
||||||
{
|
{
|
||||||
if (sourcing_name != NULL)
|
if (SOURCING_NAME != NULL)
|
||||||
{
|
{
|
||||||
if (last_sourcing_name != NULL)
|
if (last_sourcing_name != NULL)
|
||||||
return STRCMP(sourcing_name, last_sourcing_name) != 0;
|
return STRCMP(SOURCING_NAME, last_sourcing_name) != 0;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -458,12 +458,19 @@ get_emsg_source(void)
|
|||||||
{
|
{
|
||||||
char_u *Buf, *p;
|
char_u *Buf, *p;
|
||||||
|
|
||||||
if (sourcing_name != NULL && other_sourcing_name())
|
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:");
|
p = (char_u *)_("Error detected while processing %s:");
|
||||||
Buf = alloc(STRLEN(sourcing_name) + STRLEN(p));
|
Buf = alloc(STRLEN(sname) + STRLEN(p));
|
||||||
if (Buf != NULL)
|
if (Buf != NULL)
|
||||||
sprintf((char *)Buf, (char *)p, sourcing_name);
|
sprintf((char *)Buf, (char *)p, sname);
|
||||||
|
vim_free(tofree);
|
||||||
return Buf;
|
return Buf;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -481,14 +488,14 @@ get_emsg_lnum(void)
|
|||||||
|
|
||||||
// lnum is 0 when executing a command from the command line
|
// lnum is 0 when executing a command from the command line
|
||||||
// argument, we don't want a line number then
|
// argument, we don't want a line number then
|
||||||
if (sourcing_name != NULL
|
if (SOURCING_NAME != NULL
|
||||||
&& (other_sourcing_name() || sourcing_lnum != last_sourcing_lnum)
|
&& (other_sourcing_name() || SOURCING_LNUM != last_sourcing_lnum)
|
||||||
&& sourcing_lnum != 0)
|
&& SOURCING_LNUM != 0)
|
||||||
{
|
{
|
||||||
p = (char_u *)_("line %4ld:");
|
p = (char_u *)_("line %4ld:");
|
||||||
Buf = alloc(STRLEN(p) + 20);
|
Buf = alloc(STRLEN(p) + 20);
|
||||||
if (Buf != NULL)
|
if (Buf != NULL)
|
||||||
sprintf((char *)Buf, (char *)p, (long)sourcing_lnum);
|
sprintf((char *)Buf, (char *)p, (long)SOURCING_LNUM);
|
||||||
return Buf;
|
return Buf;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -516,17 +523,17 @@ msg_source(int attr)
|
|||||||
{
|
{
|
||||||
msg_attr((char *)p, HL_ATTR(HLF_N));
|
msg_attr((char *)p, HL_ATTR(HLF_N));
|
||||||
vim_free(p);
|
vim_free(p);
|
||||||
last_sourcing_lnum = sourcing_lnum; // only once for each line
|
last_sourcing_lnum = SOURCING_LNUM; // only once for each line
|
||||||
}
|
}
|
||||||
|
|
||||||
// remember the last sourcing name printed, also when it's empty
|
// remember the last sourcing name printed, also when it's empty
|
||||||
if (sourcing_name == NULL || other_sourcing_name())
|
if (SOURCING_NAME == NULL || other_sourcing_name())
|
||||||
{
|
{
|
||||||
vim_free(last_sourcing_name);
|
vim_free(last_sourcing_name);
|
||||||
if (sourcing_name == NULL)
|
if (SOURCING_NAME == NULL)
|
||||||
last_sourcing_name = NULL;
|
last_sourcing_name = NULL;
|
||||||
else
|
else
|
||||||
last_sourcing_name = vim_strsave(sourcing_name);
|
last_sourcing_name = vim_strsave(SOURCING_NAME);
|
||||||
}
|
}
|
||||||
--no_wait_return;
|
--no_wait_return;
|
||||||
}
|
}
|
||||||
@@ -2312,7 +2319,7 @@ inc_msg_scrolled(void)
|
|||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
if (*get_vim_var_str(VV_SCROLLSTART) == NUL)
|
if (*get_vim_var_str(VV_SCROLLSTART) == NUL)
|
||||||
{
|
{
|
||||||
char_u *p = sourcing_name;
|
char_u *p = SOURCING_NAME;
|
||||||
char_u *tofree = NULL;
|
char_u *tofree = NULL;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@@ -2327,7 +2334,7 @@ inc_msg_scrolled(void)
|
|||||||
if (tofree != NULL)
|
if (tofree != NULL)
|
||||||
{
|
{
|
||||||
vim_snprintf((char *)tofree, len, _("%s line %ld"),
|
vim_snprintf((char *)tofree, len, _("%s line %ld"),
|
||||||
p, (long)sourcing_lnum);
|
p, (long)SOURCING_LNUM);
|
||||||
p = tofree;
|
p = tofree;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2435,7 +2435,7 @@ set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
|
|||||||
int indir = (int)options[opt_idx].indir;
|
int indir = (int)options[opt_idx].indir;
|
||||||
sctx_T new_script_ctx = script_ctx;
|
sctx_T new_script_ctx = script_ctx;
|
||||||
|
|
||||||
new_script_ctx.sc_lnum += sourcing_lnum;
|
new_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||||
|
|
||||||
// Remember where the option was set. For local options need to do that
|
// Remember where the option was set. For local options need to do that
|
||||||
// in the buffer or window structure.
|
// in the buffer or window structure.
|
||||||
|
|||||||
@@ -602,10 +602,10 @@ func_line_start(void *cookie)
|
|||||||
funccall_T *fcp = (funccall_T *)cookie;
|
funccall_T *fcp = (funccall_T *)cookie;
|
||||||
ufunc_T *fp = fcp->func;
|
ufunc_T *fp = fcp->func;
|
||||||
|
|
||||||
if (fp->uf_profiling && sourcing_lnum >= 1
|
if (fp->uf_profiling && SOURCING_LNUM >= 1
|
||||||
&& sourcing_lnum <= fp->uf_lines.ga_len)
|
&& SOURCING_LNUM <= fp->uf_lines.ga_len)
|
||||||
{
|
{
|
||||||
fp->uf_tml_idx = sourcing_lnum - 1;
|
fp->uf_tml_idx = SOURCING_LNUM - 1;
|
||||||
// Skip continuation lines.
|
// Skip continuation lines.
|
||||||
while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
|
while (fp->uf_tml_idx > 0 && FUNCLINE(fp, fp->uf_tml_idx) == NULL)
|
||||||
--fp->uf_tml_idx;
|
--fp->uf_tml_idx;
|
||||||
@@ -906,13 +906,13 @@ script_line_start(void)
|
|||||||
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
|
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
|
||||||
return;
|
return;
|
||||||
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
si = &SCRIPT_ITEM(current_sctx.sc_sid);
|
||||||
if (si->sn_prof_on && sourcing_lnum >= 1)
|
if (si->sn_prof_on && SOURCING_LNUM >= 1)
|
||||||
{
|
{
|
||||||
// Grow the array before starting the timer, so that the time spent
|
// Grow the array before starting the timer, so that the time spent
|
||||||
// here isn't counted.
|
// here isn't counted.
|
||||||
(void)ga_grow(&si->sn_prl_ga,
|
(void)ga_grow(&si->sn_prl_ga,
|
||||||
(int)(sourcing_lnum - si->sn_prl_ga.ga_len));
|
(int)(SOURCING_LNUM - si->sn_prl_ga.ga_len));
|
||||||
si->sn_prl_idx = sourcing_lnum - 1;
|
si->sn_prl_idx = SOURCING_LNUM - 1;
|
||||||
while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
|
while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
|
||||||
&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
|
&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
/* scriptfile.c */
|
/* 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);
|
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_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);
|
int do_in_runtimepath(char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie);
|
||||||
|
|||||||
151
src/scriptfile.c
151
src/scriptfile.c
@@ -18,6 +18,122 @@
|
|||||||
static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
|
static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
|
||||||
#endif
|
#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}"
|
* ":runtime [what] {name}"
|
||||||
*/
|
*/
|
||||||
@@ -947,8 +1063,6 @@ do_source(
|
|||||||
int is_vimrc) // DOSO_ value
|
int is_vimrc) // DOSO_ value
|
||||||
{
|
{
|
||||||
struct source_cookie cookie;
|
struct source_cookie cookie;
|
||||||
char_u *save_sourcing_name;
|
|
||||||
linenr_T save_sourcing_lnum;
|
|
||||||
char_u *p;
|
char_u *p;
|
||||||
char_u *fname_exp;
|
char_u *fname_exp;
|
||||||
char_u *firstline = NULL;
|
char_u *firstline = NULL;
|
||||||
@@ -1039,11 +1153,11 @@ do_source(
|
|||||||
if (p_verbose > 0)
|
if (p_verbose > 0)
|
||||||
{
|
{
|
||||||
verbose_enter();
|
verbose_enter();
|
||||||
if (sourcing_name == NULL)
|
if (SOURCING_NAME == NULL)
|
||||||
smsg(_("could not source \"%s\""), fname);
|
smsg(_("could not source \"%s\""), fname);
|
||||||
else
|
else
|
||||||
smsg(_("line %ld: could not source \"%s\""),
|
smsg(_("line %ld: could not source \"%s\""),
|
||||||
sourcing_lnum, fname);
|
SOURCING_LNUM, fname);
|
||||||
verbose_leave();
|
verbose_leave();
|
||||||
}
|
}
|
||||||
goto theend;
|
goto theend;
|
||||||
@@ -1055,11 +1169,10 @@ do_source(
|
|||||||
if (p_verbose > 1)
|
if (p_verbose > 1)
|
||||||
{
|
{
|
||||||
verbose_enter();
|
verbose_enter();
|
||||||
if (sourcing_name == NULL)
|
if (SOURCING_NAME == NULL)
|
||||||
smsg(_("sourcing \"%s\""), fname);
|
smsg(_("sourcing \"%s\""), fname);
|
||||||
else
|
else
|
||||||
smsg(_("line %ld: sourcing \"%s\""),
|
smsg(_("line %ld: sourcing \"%s\""), SOURCING_LNUM, fname);
|
||||||
sourcing_lnum, fname);
|
|
||||||
verbose_leave();
|
verbose_leave();
|
||||||
}
|
}
|
||||||
if (is_vimrc == DOSO_VIMRC)
|
if (is_vimrc == DOSO_VIMRC)
|
||||||
@@ -1090,10 +1203,7 @@ do_source(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Keep the sourcing name/lnum, for recursive calls.
|
// Keep the sourcing name/lnum, for recursive calls.
|
||||||
save_sourcing_name = sourcing_name;
|
estack_push(ETYPE_SCRIPT, fname_exp, 0);
|
||||||
sourcing_name = fname_exp;
|
|
||||||
save_sourcing_lnum = sourcing_lnum;
|
|
||||||
sourcing_lnum = 0;
|
|
||||||
|
|
||||||
#ifdef STARTUPTIME
|
#ifdef STARTUPTIME
|
||||||
if (time_fd != NULL)
|
if (time_fd != NULL)
|
||||||
@@ -1233,14 +1343,13 @@ do_source(
|
|||||||
|
|
||||||
if (got_int)
|
if (got_int)
|
||||||
emsg(_(e_interr));
|
emsg(_(e_interr));
|
||||||
sourcing_name = save_sourcing_name;
|
estack_pop();
|
||||||
sourcing_lnum = save_sourcing_lnum;
|
|
||||||
if (p_verbose > 1)
|
if (p_verbose > 1)
|
||||||
{
|
{
|
||||||
verbose_enter();
|
verbose_enter();
|
||||||
smsg(_("finished sourcing %s"), fname);
|
smsg(_("finished sourcing %s"), fname);
|
||||||
if (sourcing_name != NULL)
|
if (SOURCING_NAME != NULL)
|
||||||
smsg(_("continuing in %s"), sourcing_name);
|
smsg(_("continuing in %s"), SOURCING_NAME);
|
||||||
verbose_leave();
|
verbose_leave();
|
||||||
}
|
}
|
||||||
#ifdef STARTUPTIME
|
#ifdef STARTUPTIME
|
||||||
@@ -1381,7 +1490,7 @@ get_sourced_lnum(char_u *(*fgetline)(int, void *, int, int), void *cookie)
|
|||||||
{
|
{
|
||||||
return fgetline == getsourceline
|
return fgetline == getsourceline
|
||||||
? ((struct source_cookie *)cookie)->sourcing_lnum
|
? ((struct source_cookie *)cookie)->sourcing_lnum
|
||||||
: sourcing_lnum;
|
: SOURCING_LNUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char_u *
|
static char_u *
|
||||||
@@ -1507,7 +1616,7 @@ getsourceline(int c UNUSED, void *cookie, int indent UNUSED, int do_concat)
|
|||||||
// If breakpoints have been added/deleted need to check for it.
|
// If breakpoints have been added/deleted need to check for it.
|
||||||
if (sp->dbg_tick < debug_tick)
|
if (sp->dbg_tick < debug_tick)
|
||||||
{
|
{
|
||||||
sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
|
sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, SOURCING_LNUM);
|
||||||
sp->dbg_tick = debug_tick;
|
sp->dbg_tick = debug_tick;
|
||||||
}
|
}
|
||||||
# ifdef FEAT_PROFILE
|
# ifdef FEAT_PROFILE
|
||||||
@@ -1517,7 +1626,7 @@ getsourceline(int c UNUSED, void *cookie, int indent UNUSED, int do_concat)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set the current sourcing line number.
|
// Set the current sourcing line number.
|
||||||
sourcing_lnum = sp->sourcing_lnum + 1;
|
SOURCING_LNUM = sp->sourcing_lnum + 1;
|
||||||
|
|
||||||
// Get current line. If there is a read-ahead line, use it, otherwise get
|
// Get current line. If there is a read-ahead line, use it, otherwise get
|
||||||
// one now.
|
// one now.
|
||||||
@@ -1602,11 +1711,11 @@ getsourceline(int c UNUSED, void *cookie, int indent UNUSED, int do_concat)
|
|||||||
|
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
// Did we encounter a breakpoint?
|
// Did we encounter a breakpoint?
|
||||||
if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum)
|
if (sp->breakpoint != 0 && sp->breakpoint <= SOURCING_LNUM)
|
||||||
{
|
{
|
||||||
dbg_breakpoint(sp->fname, sourcing_lnum);
|
dbg_breakpoint(sp->fname, SOURCING_LNUM);
|
||||||
// Find next breakpoint.
|
// Find next breakpoint.
|
||||||
sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, sourcing_lnum);
|
sp->breakpoint = dbg_find_breakpoint(TRUE, sp->fname, SOURCING_LNUM);
|
||||||
sp->dbg_tick = debug_tick;
|
sp->dbg_tick = debug_tick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -349,8 +349,6 @@ spell_load_file(
|
|||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
int len;
|
int len;
|
||||||
char_u *save_sourcing_name = sourcing_name;
|
|
||||||
linenr_T save_sourcing_lnum = sourcing_lnum;
|
|
||||||
slang_T *lp = NULL;
|
slang_T *lp = NULL;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
int res;
|
int res;
|
||||||
@@ -393,8 +391,7 @@ spell_load_file(
|
|||||||
lp = old_lp;
|
lp = old_lp;
|
||||||
|
|
||||||
// Set sourcing_name, so that error messages mention the file name.
|
// Set sourcing_name, so that error messages mention the file name.
|
||||||
sourcing_name = fname;
|
estack_push(ETYPE_SPELL, fname, 0);
|
||||||
sourcing_lnum = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* <HEADER>: <fileID>
|
* <HEADER>: <fileID>
|
||||||
@@ -581,8 +578,7 @@ endFAIL:
|
|||||||
endOK:
|
endOK:
|
||||||
if (fd != NULL)
|
if (fd != NULL)
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
sourcing_name = save_sourcing_name;
|
estack_pop();
|
||||||
sourcing_lnum = save_sourcing_lnum;
|
|
||||||
|
|
||||||
return lp;
|
return lp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1496,6 +1496,8 @@ typedef struct
|
|||||||
// used for s: variables
|
// used for s: variables
|
||||||
int uf_refcount; // reference count, see func_name_refcount()
|
int uf_refcount; // reference count, see func_name_refcount()
|
||||||
funccall_T *uf_scoped; // l: local variables for closure
|
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
|
char_u uf_name[1]; // name of function (actually longer); can
|
||||||
// start with <SNR>123_ (<SNR> is K_SPECIAL
|
// start with <SNR>123_ (<SNR> is K_SPECIAL
|
||||||
// KS_EXTRA KE_SNR)
|
// KS_EXTRA KE_SNR)
|
||||||
@@ -1665,6 +1667,38 @@ struct partial_S
|
|||||||
dict_T *pt_dict; // dict for "self"
|
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().
|
// Information returned by get_tty_info().
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int backspace; // what the Backspace key produces
|
int backspace; // what the Backspace key produces
|
||||||
|
|||||||
@@ -2277,7 +2277,7 @@ add_termcap_entry(char_u *name, int force)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sourcing_name == NULL)
|
if (SOURCING_NAME == NULL)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_TGETENT
|
#ifdef HAVE_TGETENT
|
||||||
if (error_msg != NULL)
|
if (error_msg != NULL)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func RunDbgCmd(buf, cmd, ...)
|
|||||||
" Verify the expected output
|
" Verify the expected output
|
||||||
let lnum = 20 - len(a:1)
|
let lnum = 20 - len(a:1)
|
||||||
for l in a:1
|
for l in a:1
|
||||||
call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))})
|
call WaitForAssert({-> assert_equal(l, term_getline(a:buf, lnum))}, 200)
|
||||||
let lnum += 1
|
let lnum += 1
|
||||||
endfor
|
endfor
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -21,22 +21,24 @@
|
|||||||
static void
|
static void
|
||||||
prepare_assert_error(garray_T *gap)
|
prepare_assert_error(garray_T *gap)
|
||||||
{
|
{
|
||||||
char buf[NUMBUFLEN];
|
char buf[NUMBUFLEN];
|
||||||
|
char_u *sname = estack_sfile();
|
||||||
|
|
||||||
ga_init2(gap, 1, 100);
|
ga_init2(gap, 1, 100);
|
||||||
if (sourcing_name != NULL)
|
if (sname != NULL)
|
||||||
{
|
{
|
||||||
ga_concat(gap, sourcing_name);
|
ga_concat(gap, sname);
|
||||||
if (sourcing_lnum > 0)
|
if (SOURCING_LNUM > 0)
|
||||||
ga_concat(gap, (char_u *)" ");
|
ga_concat(gap, (char_u *)" ");
|
||||||
}
|
}
|
||||||
if (sourcing_lnum > 0)
|
if (SOURCING_LNUM > 0)
|
||||||
{
|
{
|
||||||
sprintf(buf, "line %ld", (long)sourcing_lnum);
|
sprintf(buf, "line %ld", (long)SOURCING_LNUM);
|
||||||
ga_concat(gap, (char_u *)buf);
|
ga_concat(gap, (char_u *)buf);
|
||||||
}
|
}
|
||||||
if (sourcing_name != NULL || sourcing_lnum > 0)
|
if (sname != NULL || SOURCING_LNUM > 0)
|
||||||
ga_concat(gap, (char_u *)": ");
|
ga_concat(gap, (char_u *)": ");
|
||||||
|
vim_free(sname);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ find_ucmd(
|
|||||||
{
|
{
|
||||||
xp->xp_arg = uc->uc_compl_arg;
|
xp->xp_arg = uc->uc_compl_arg;
|
||||||
xp->xp_script_ctx = uc->uc_script_ctx;
|
xp->xp_script_ctx = uc->uc_script_ctx;
|
||||||
xp->xp_script_ctx.sc_lnum += sourcing_lnum;
|
xp->xp_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
// Do not search for further abbreviations
|
// Do not search for further abbreviations
|
||||||
@@ -956,7 +956,7 @@ uc_add_command(
|
|||||||
cmd->uc_compl = compl;
|
cmd->uc_compl = compl;
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
cmd->uc_script_ctx = current_sctx;
|
cmd->uc_script_ctx = current_sctx;
|
||||||
cmd->uc_script_ctx.sc_lnum += sourcing_lnum;
|
cmd->uc_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||||
cmd->uc_compl_arg = compl_arg;
|
cmd->uc_compl_arg = compl_arg;
|
||||||
#endif
|
#endif
|
||||||
cmd->uc_addr_type = addr_type;
|
cmd->uc_addr_type = addr_type;
|
||||||
|
|||||||
161
src/userfunc.c
161
src/userfunc.c
@@ -226,6 +226,22 @@ register_closure(ufunc_T *fp)
|
|||||||
return OK;
|
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".
|
* Parse a lambda expression and get a Funcref from "*arg".
|
||||||
* Return OK or FAIL. Returns NOTDONE for dict or {expr}.
|
* Return OK or FAIL. Returns NOTDONE for dict or {expr}.
|
||||||
@@ -309,7 +325,7 @@ get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
vim_strncpy(p + 7, s, e - s);
|
vim_strncpy(p + 7, s, e - s);
|
||||||
|
|
||||||
fp->uf_refcount = 1;
|
fp->uf_refcount = 1;
|
||||||
STRCPY(fp->uf_name, name);
|
set_ufunc_name(fp, name);
|
||||||
hash_add(&func_hashtab, UF2HIKEY(fp));
|
hash_add(&func_hashtab, UF2HIKEY(fp));
|
||||||
fp->uf_args = newargs;
|
fp->uf_args = newargs;
|
||||||
ga_init(&fp->uf_def_args);
|
ga_init(&fp->uf_def_args);
|
||||||
@@ -333,7 +349,7 @@ get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate)
|
|||||||
fp->uf_flags = flags;
|
fp->uf_flags = flags;
|
||||||
fp->uf_calls = 0;
|
fp->uf_calls = 0;
|
||||||
fp->uf_script_ctx = current_sctx;
|
fp->uf_script_ctx = current_sctx;
|
||||||
fp->uf_script_ctx.sc_lnum += sourcing_lnum - newlines.ga_len;
|
fp->uf_script_ctx.sc_lnum += SOURCING_LNUM - newlines.ga_len;
|
||||||
|
|
||||||
pt->pt_func = fp;
|
pt->pt_func = fp;
|
||||||
pt->pt_refcount = 1;
|
pt->pt_refcount = 1;
|
||||||
@@ -759,8 +775,6 @@ call_user_func(
|
|||||||
linenr_T lastline, // last line of range
|
linenr_T lastline, // last line of range
|
||||||
dict_T *selfdict) // Dictionary for "self"
|
dict_T *selfdict) // Dictionary for "self"
|
||||||
{
|
{
|
||||||
char_u *save_sourcing_name;
|
|
||||||
linenr_T save_sourcing_lnum;
|
|
||||||
sctx_T save_current_sctx;
|
sctx_T save_current_sctx;
|
||||||
int using_sandbox = FALSE;
|
int using_sandbox = FALSE;
|
||||||
funccall_T *fc;
|
funccall_T *fc;
|
||||||
@@ -774,7 +788,6 @@ call_user_func(
|
|||||||
int islambda = FALSE;
|
int islambda = FALSE;
|
||||||
char_u numbuf[NUMBUFLEN];
|
char_u numbuf[NUMBUFLEN];
|
||||||
char_u *name;
|
char_u *name;
|
||||||
size_t len;
|
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
proftime_T wait_start;
|
proftime_T wait_start;
|
||||||
proftime_T call_start;
|
proftime_T call_start;
|
||||||
@@ -948,9 +961,6 @@ call_user_func(
|
|||||||
|
|
||||||
// Don't redraw while executing the function.
|
// Don't redraw while executing the function.
|
||||||
++RedrawingDisabled;
|
++RedrawingDisabled;
|
||||||
save_sourcing_name = sourcing_name;
|
|
||||||
save_sourcing_lnum = sourcing_lnum;
|
|
||||||
sourcing_lnum = 1;
|
|
||||||
|
|
||||||
if (fp->uf_flags & FC_SANDBOX)
|
if (fp->uf_flags & FC_SANDBOX)
|
||||||
{
|
{
|
||||||
@@ -958,65 +968,51 @@ call_user_func(
|
|||||||
++sandbox;
|
++sandbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
// need space for function name + ("function " + 3) or "[number]"
|
estack_push_ufunc(ETYPE_UFUNC, fp, 1);
|
||||||
len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name))
|
if (p_verbose >= 12)
|
||||||
+ STRLEN(fp->uf_name) + 20;
|
|
||||||
sourcing_name = alloc(len);
|
|
||||||
if (sourcing_name != NULL)
|
|
||||||
{
|
{
|
||||||
if (save_sourcing_name != NULL
|
++no_wait_return;
|
||||||
&& STRNCMP(save_sourcing_name, "function ", 9) == 0)
|
verbose_enter_scroll();
|
||||||
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)
|
smsg(_("calling %s"), SOURCING_NAME);
|
||||||
|
if (p_verbose >= 14)
|
||||||
{
|
{
|
||||||
++no_wait_return;
|
char_u buf[MSG_BUF_LEN];
|
||||||
verbose_enter_scroll();
|
char_u numbuf2[NUMBUFLEN];
|
||||||
|
char_u *tofree;
|
||||||
|
char_u *s;
|
||||||
|
|
||||||
smsg(_("calling %s"), sourcing_name);
|
msg_puts("(");
|
||||||
if (p_verbose >= 14)
|
for (i = 0; i < argcount; ++i)
|
||||||
{
|
{
|
||||||
char_u buf[MSG_BUF_LEN];
|
if (i > 0)
|
||||||
char_u numbuf2[NUMBUFLEN];
|
msg_puts(", ");
|
||||||
char_u *tofree;
|
if (argvars[i].v_type == VAR_NUMBER)
|
||||||
char_u *s;
|
msg_outnum((long)argvars[i].vval.v_number);
|
||||||
|
else
|
||||||
msg_puts("(");
|
|
||||||
for (i = 0; i < argcount; ++i)
|
|
||||||
{
|
{
|
||||||
if (i > 0)
|
// Do not want errors such as E724 here.
|
||||||
msg_puts(", ");
|
++emsg_off;
|
||||||
if (argvars[i].v_type == VAR_NUMBER)
|
s = tv2string(&argvars[i], &tofree, numbuf2, 0);
|
||||||
msg_outnum((long)argvars[i].vval.v_number);
|
--emsg_off;
|
||||||
else
|
if (s != NULL)
|
||||||
{
|
{
|
||||||
// Do not want errors such as E724 here.
|
if (vim_strsize(s) > MSG_BUF_CLEN)
|
||||||
++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;
|
||||||
trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
|
|
||||||
s = buf;
|
|
||||||
}
|
|
||||||
msg_puts((char *)s);
|
|
||||||
vim_free(tofree);
|
|
||||||
}
|
}
|
||||||
|
msg_puts((char *)s);
|
||||||
|
vim_free(tofree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg_puts(")");
|
|
||||||
}
|
}
|
||||||
msg_puts("\n"); // don't overwrite this either
|
msg_puts(")");
|
||||||
|
|
||||||
verbose_leave_scroll();
|
|
||||||
--no_wait_return;
|
|
||||||
}
|
}
|
||||||
|
msg_puts("\n"); // don't overwrite this either
|
||||||
|
|
||||||
|
verbose_leave_scroll();
|
||||||
|
--no_wait_return;
|
||||||
}
|
}
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
if (do_profiling == PROF_YES)
|
if (do_profiling == PROF_YES)
|
||||||
@@ -1085,9 +1081,9 @@ call_user_func(
|
|||||||
verbose_enter_scroll();
|
verbose_enter_scroll();
|
||||||
|
|
||||||
if (aborting())
|
if (aborting())
|
||||||
smsg(_("%s aborted"), sourcing_name);
|
smsg(_("%s aborted"), SOURCING_NAME);
|
||||||
else if (fc->rettv->v_type == VAR_NUMBER)
|
else if (fc->rettv->v_type == VAR_NUMBER)
|
||||||
smsg(_("%s returning #%ld"), sourcing_name,
|
smsg(_("%s returning #%ld"), SOURCING_NAME,
|
||||||
(long)fc->rettv->vval.v_number);
|
(long)fc->rettv->vval.v_number);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1109,7 +1105,7 @@ call_user_func(
|
|||||||
trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
|
trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
|
||||||
s = buf;
|
s = buf;
|
||||||
}
|
}
|
||||||
smsg(_("%s returning %s"), sourcing_name, s);
|
smsg(_("%s returning %s"), SOURCING_NAME, s);
|
||||||
vim_free(tofree);
|
vim_free(tofree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1119,9 +1115,7 @@ call_user_func(
|
|||||||
--no_wait_return;
|
--no_wait_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vim_free(sourcing_name);
|
estack_pop();
|
||||||
sourcing_name = save_sourcing_name;
|
|
||||||
sourcing_lnum = save_sourcing_lnum;
|
|
||||||
current_sctx = save_current_sctx;
|
current_sctx = save_current_sctx;
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
if (do_profiling == PROF_YES)
|
if (do_profiling == PROF_YES)
|
||||||
@@ -1130,12 +1124,12 @@ call_user_func(
|
|||||||
if (using_sandbox)
|
if (using_sandbox)
|
||||||
--sandbox;
|
--sandbox;
|
||||||
|
|
||||||
if (p_verbose >= 12 && sourcing_name != NULL)
|
if (p_verbose >= 12 && SOURCING_NAME != NULL)
|
||||||
{
|
{
|
||||||
++no_wait_return;
|
++no_wait_return;
|
||||||
verbose_enter_scroll();
|
verbose_enter_scroll();
|
||||||
|
|
||||||
smsg(_("continuing in %s"), sourcing_name);
|
smsg(_("continuing in %s"), SOURCING_NAME);
|
||||||
msg_puts("\n"); // don't overwrite this either
|
msg_puts("\n"); // don't overwrite this either
|
||||||
|
|
||||||
verbose_leave_scroll();
|
verbose_leave_scroll();
|
||||||
@@ -1204,13 +1198,11 @@ func_clear_items(ufunc_T *fp)
|
|||||||
ga_clear_strings(&(fp->uf_args));
|
ga_clear_strings(&(fp->uf_args));
|
||||||
ga_clear_strings(&(fp->uf_def_args));
|
ga_clear_strings(&(fp->uf_def_args));
|
||||||
ga_clear_strings(&(fp->uf_lines));
|
ga_clear_strings(&(fp->uf_lines));
|
||||||
|
VIM_CLEAR(fp->uf_name_exp);
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
vim_free(fp->uf_tml_count);
|
VIM_CLEAR(fp->uf_tml_count);
|
||||||
fp->uf_tml_count = NULL;
|
VIM_CLEAR(fp->uf_tml_total);
|
||||||
vim_free(fp->uf_tml_total);
|
VIM_CLEAR(fp->uf_tml_self);
|
||||||
fp->uf_tml_total = NULL;
|
|
||||||
vim_free(fp->uf_tml_self);
|
|
||||||
fp->uf_tml_self = NULL;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1736,11 +1728,8 @@ list_func_head(ufunc_T *fp, int indent)
|
|||||||
if (indent)
|
if (indent)
|
||||||
msg_puts(" ");
|
msg_puts(" ");
|
||||||
msg_puts("function ");
|
msg_puts("function ");
|
||||||
if (fp->uf_name[0] == K_SPECIAL)
|
if (fp->uf_name_exp != NULL)
|
||||||
{
|
msg_puts((char *)fp->uf_name_exp);
|
||||||
msg_puts_attr("<SNR>", HL_ATTR(HLF_8));
|
|
||||||
msg_puts((char *)fp->uf_name + 3);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
msg_puts((char *)fp->uf_name);
|
msg_puts((char *)fp->uf_name);
|
||||||
msg_putchar('(');
|
msg_putchar('(');
|
||||||
@@ -2308,7 +2297,7 @@ ex_function(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save the starting line number.
|
// Save the starting line number.
|
||||||
sourcing_lnum_top = sourcing_lnum;
|
sourcing_lnum_top = SOURCING_LNUM;
|
||||||
|
|
||||||
indent = 2;
|
indent = 2;
|
||||||
nesting = 0;
|
nesting = 0;
|
||||||
@@ -2351,10 +2340,10 @@ ex_function(exarg_T *eap)
|
|||||||
goto erret;
|
goto erret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect line continuation: sourcing_lnum increased more than one.
|
// Detect line continuation: SOURCING_LNUM increased more than one.
|
||||||
sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
|
sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
|
||||||
if (sourcing_lnum < sourcing_lnum_off)
|
if (SOURCING_LNUM < sourcing_lnum_off)
|
||||||
sourcing_lnum_off -= sourcing_lnum;
|
sourcing_lnum_off -= SOURCING_LNUM;
|
||||||
else
|
else
|
||||||
sourcing_lnum_off = 0;
|
sourcing_lnum_off = 0;
|
||||||
|
|
||||||
@@ -2631,16 +2620,16 @@ ex_function(exarg_T *eap)
|
|||||||
|
|
||||||
// Check that the autoload name matches the script name.
|
// Check that the autoload name matches the script name.
|
||||||
j = FAIL;
|
j = FAIL;
|
||||||
if (sourcing_name != NULL)
|
if (SOURCING_NAME != NULL)
|
||||||
{
|
{
|
||||||
scriptname = autoload_name(name);
|
scriptname = autoload_name(name);
|
||||||
if (scriptname != NULL)
|
if (scriptname != NULL)
|
||||||
{
|
{
|
||||||
p = vim_strchr(scriptname, '/');
|
p = vim_strchr(scriptname, '/');
|
||||||
plen = (int)STRLEN(p);
|
plen = (int)STRLEN(p);
|
||||||
slen = (int)STRLEN(sourcing_name);
|
slen = (int)STRLEN(SOURCING_NAME);
|
||||||
if (slen > plen && fnamecmp(p,
|
if (slen > plen && fnamecmp(p,
|
||||||
sourcing_name + slen - plen) == 0)
|
SOURCING_NAME + slen - plen) == 0)
|
||||||
j = OK;
|
j = OK;
|
||||||
vim_free(scriptname);
|
vim_free(scriptname);
|
||||||
}
|
}
|
||||||
@@ -2685,7 +2674,7 @@ ex_function(exarg_T *eap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// insert the new function in the function list
|
// insert the new function in the function list
|
||||||
STRCPY(fp->uf_name, name);
|
set_ufunc_name(fp, name);
|
||||||
if (overwrite)
|
if (overwrite)
|
||||||
{
|
{
|
||||||
hi = hash_find(&func_hashtab, name);
|
hi = hash_find(&func_hashtab, name);
|
||||||
@@ -3353,7 +3342,7 @@ get_func_line(
|
|||||||
if (fcp->dbg_tick != debug_tick)
|
if (fcp->dbg_tick != debug_tick)
|
||||||
{
|
{
|
||||||
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
|
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
|
||||||
sourcing_lnum);
|
SOURCING_LNUM);
|
||||||
fcp->dbg_tick = debug_tick;
|
fcp->dbg_tick = debug_tick;
|
||||||
}
|
}
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
@@ -3376,7 +3365,7 @@ get_func_line(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
|
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
|
||||||
sourcing_lnum = fcp->linenr;
|
SOURCING_LNUM = fcp->linenr;
|
||||||
#ifdef FEAT_PROFILE
|
#ifdef FEAT_PROFILE
|
||||||
if (do_profiling == PROF_YES)
|
if (do_profiling == PROF_YES)
|
||||||
func_line_start(cookie);
|
func_line_start(cookie);
|
||||||
@@ -3385,12 +3374,12 @@ get_func_line(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Did we encounter a breakpoint?
|
// Did we encounter a breakpoint?
|
||||||
if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum)
|
if (fcp->breakpoint != 0 && fcp->breakpoint <= SOURCING_LNUM)
|
||||||
{
|
{
|
||||||
dbg_breakpoint(fp->uf_name, sourcing_lnum);
|
dbg_breakpoint(fp->uf_name, SOURCING_LNUM);
|
||||||
// Find next breakpoint.
|
// Find next breakpoint.
|
||||||
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
|
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
|
||||||
sourcing_lnum);
|
SOURCING_LNUM);
|
||||||
fcp->dbg_tick = debug_tick;
|
fcp->dbg_tick = debug_tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -742,6 +742,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
56,
|
||||||
/**/
|
/**/
|
||||||
55,
|
55,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user