mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-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.
1a47ae32cd
Omit test_debugger.vim: superseded by later patches.
Omit check_map_keycodes(): N/A.
Omit kword_test.c: N/A (converted to a unit test).
This commit is contained in:
parent
c1cbe3fb3d
commit
f52c236c5b
@ -27,6 +27,7 @@
|
||||
#include "nvim/os/input.h"
|
||||
#include "nvim/profile.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/search.h"
|
||||
#include "nvim/state.h"
|
||||
#include "nvim/ui_compositor.h"
|
||||
@ -1143,7 +1144,7 @@ int autocmd_register(int64_t id, event_T event, char *pat, int patlen, int group
|
||||
ac->id = id;
|
||||
ac->exec = aucmd_exec_copy(aucmd);
|
||||
ac->script_ctx = current_sctx;
|
||||
ac->script_ctx.sc_lnum += sourcing_lnum;
|
||||
ac->script_ctx.sc_lnum += SOURCING_LNUM;
|
||||
nlua_set_sctx(&ac->script_ctx);
|
||||
ac->next = NULL;
|
||||
ac->once = once;
|
||||
@ -1771,10 +1772,9 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
|
||||
// Don't redraw while doing autocommands.
|
||||
RedrawingDisabled++;
|
||||
char *save_sourcing_name = sourcing_name;
|
||||
sourcing_name = NULL; // don't free this one
|
||||
linenr_T save_sourcing_lnum = sourcing_lnum;
|
||||
sourcing_lnum = 0; // no line number here
|
||||
|
||||
// name and lnum are filled in later
|
||||
estack_push(ETYPE_AUCMD, NULL, 0);
|
||||
|
||||
const sctx_T save_current_sctx = current_sctx;
|
||||
|
||||
@ -1878,9 +1878,8 @@ bool apply_autocmds_group(event_T event, char *fname, char *fname_io, bool force
|
||||
autocmd_busy = save_autocmd_busy;
|
||||
filechangeshell_busy = false;
|
||||
autocmd_nested = save_autocmd_nested;
|
||||
xfree(sourcing_name);
|
||||
sourcing_name = save_sourcing_name;
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
xfree(SOURCING_NAME);
|
||||
estack_pop();
|
||||
xfree(autocmd_fname);
|
||||
autocmd_fname = save_autocmd_fname;
|
||||
autocmd_bufnr = save_autocmd_bufnr;
|
||||
@ -1983,8 +1982,9 @@ void auto_next_pat(AutoPatCmd *apc, int stop_at_last)
|
||||
AutoPat *ap;
|
||||
AutoCmd *cp;
|
||||
char *s;
|
||||
char **const sourcing_namep = &SOURCING_NAME;
|
||||
|
||||
XFREE_CLEAR(sourcing_name);
|
||||
XFREE_CLEAR(*sourcing_namep);
|
||||
|
||||
for (ap = apc->curpat; ap != NULL && !got_int; ap = ap->next) {
|
||||
apc->curpat = NULL;
|
||||
@ -2009,11 +2009,11 @@ void auto_next_pat(AutoPatCmd *apc, int stop_at_last)
|
||||
const size_t sourcing_name_len
|
||||
= (STRLEN(s) + strlen(name) + (size_t)ap->patlen + 1);
|
||||
|
||||
sourcing_name = xmalloc(sourcing_name_len);
|
||||
snprintf(sourcing_name, sourcing_name_len, s, name, ap->pat);
|
||||
*sourcing_namep = xmalloc(sourcing_name_len);
|
||||
snprintf(*sourcing_namep, sourcing_name_len, s, name, ap->pat);
|
||||
if (p_verbose >= 8) {
|
||||
verbose_enter();
|
||||
smsg(_("Executing %s"), sourcing_name);
|
||||
smsg(_("Executing %s"), *sourcing_namep);
|
||||
verbose_leave();
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,8 @@ typedef struct {
|
||||
bool save_VIsual_active; ///< saved VIsual_active
|
||||
} aco_save_T;
|
||||
|
||||
typedef struct AutoCmd {
|
||||
typedef struct AutoCmd_S AutoCmd;
|
||||
struct AutoCmd_S {
|
||||
AucmdExecutable exec;
|
||||
bool once; // "One shot": removed after execution
|
||||
bool nested; // If autocommands nest here
|
||||
@ -30,11 +31,12 @@ typedef struct AutoCmd {
|
||||
int64_t id; // ID used for uniquely tracking an autocmd.
|
||||
sctx_T script_ctx; // script context where defined
|
||||
char *desc; // Description for the autocmd.
|
||||
struct AutoCmd *next; // Next AutoCmd in list
|
||||
} AutoCmd;
|
||||
AutoCmd *next; // Next AutoCmd in list
|
||||
};
|
||||
|
||||
typedef struct AutoPat {
|
||||
struct AutoPat *next; // next AutoPat in AutoPat list; MUST
|
||||
typedef struct AutoPat_S AutoPat;
|
||||
struct AutoPat_S {
|
||||
AutoPat *next; // next AutoPat in AutoPat list; MUST
|
||||
// be the first entry
|
||||
char *pat; // pattern as typed (NULL when pattern
|
||||
// has been removed)
|
||||
@ -45,10 +47,11 @@ typedef struct AutoPat {
|
||||
int buflocal_nr; // !=0 for buffer-local AutoPat
|
||||
char allow_dirs; // Pattern may match whole path
|
||||
char last; // last pattern for apply_autocmds()
|
||||
} AutoPat;
|
||||
};
|
||||
|
||||
/// Struct used to keep status while executing autocommands for an event.
|
||||
typedef struct AutoPatCmd {
|
||||
typedef struct AutoPatCmd_S AutoPatCmd;
|
||||
struct AutoPatCmd_S {
|
||||
AutoPat *curpat; // next AutoPat to examine
|
||||
AutoCmd *nextcmd; // next AutoCmd to execute
|
||||
int group; // group being used
|
||||
@ -58,8 +61,8 @@ typedef struct AutoPatCmd {
|
||||
event_T event; // current event
|
||||
int arg_bufnr; // initially equal to <abuf>, set to zero when buf is deleted
|
||||
Object *data; // arbitrary data
|
||||
struct AutoPatCmd *next; // chain of active apc-s for auto-invalidation
|
||||
} AutoPatCmd;
|
||||
AutoPatCmd *next; // chain of active apc-s for auto-invalidation
|
||||
};
|
||||
|
||||
// Set by the apply_autocmds_group function if the given event is equal to
|
||||
// EVENT_FILETYPE. Used by the readfile function in order to determine if
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include "nvim/plines.h"
|
||||
#include "nvim/quickfix.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/sign.h"
|
||||
#include "nvim/spell.h"
|
||||
@ -5149,8 +5150,6 @@ static int chk_modeline(linenr_T lnum, int flags)
|
||||
intmax_t vers;
|
||||
int end;
|
||||
int retval = OK;
|
||||
char *save_sourcing_name;
|
||||
linenr_T save_sourcing_lnum;
|
||||
|
||||
prev = -1;
|
||||
for (s = (char *)ml_get(lnum); *s != NUL; s++) {
|
||||
@ -5195,10 +5194,8 @@ static int chk_modeline(linenr_T lnum, int flags)
|
||||
|
||||
s = linecopy = xstrdup(s); // copy the line, it will change
|
||||
|
||||
save_sourcing_lnum = sourcing_lnum;
|
||||
save_sourcing_name = sourcing_name;
|
||||
sourcing_lnum = lnum; // prepare for emsg()
|
||||
sourcing_name = "modelines";
|
||||
// prepare for emsg()
|
||||
estack_push(ETYPE_MODELINE, "modelines", lnum);
|
||||
|
||||
end = false;
|
||||
while (end == false) {
|
||||
@ -5238,7 +5235,7 @@ static int chk_modeline(linenr_T lnum, int flags)
|
||||
const sctx_T save_current_sctx = current_sctx;
|
||||
current_sctx.sc_sid = SID_MODELINE;
|
||||
current_sctx.sc_seq = 0;
|
||||
current_sctx.sc_lnum = 0;
|
||||
current_sctx.sc_lnum = lnum;
|
||||
// Make sure no risky things are executed as a side effect.
|
||||
secure = 1;
|
||||
|
||||
@ -5253,9 +5250,7 @@ static int chk_modeline(linenr_T lnum, int flags)
|
||||
s = e + 1; // advance to next part
|
||||
}
|
||||
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
sourcing_name = save_sourcing_name;
|
||||
|
||||
estack_pop();
|
||||
xfree(linecopy);
|
||||
|
||||
return retval;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "nvim/os/os.h"
|
||||
#include "nvim/pos.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/types.h"
|
||||
#include "nvim/vim.h"
|
||||
@ -98,14 +99,17 @@ void do_debug(char_u *cmd)
|
||||
xfree(debug_newval);
|
||||
debug_newval = NULL;
|
||||
}
|
||||
if (sourcing_name != NULL) {
|
||||
msg(sourcing_name);
|
||||
char *sname = estack_sfile();
|
||||
if (sname != NULL) {
|
||||
msg(sname);
|
||||
}
|
||||
if (sourcing_lnum != 0) {
|
||||
smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd);
|
||||
xfree(sname);
|
||||
if (SOURCING_LNUM != 0) {
|
||||
smsg(_("line %" PRId64 ": %s"), (int64_t)SOURCING_LNUM, cmd);
|
||||
} else {
|
||||
smsg(_("cmd: %s"), cmd);
|
||||
}
|
||||
|
||||
// Repeat getting a command and executing it.
|
||||
for (;;) {
|
||||
msg_scroll = true;
|
||||
@ -287,12 +291,12 @@ void do_debug(char_u *cmd)
|
||||
debug_did_msg = true;
|
||||
}
|
||||
|
||||
static int get_maxbacktrace_level(void)
|
||||
static int get_maxbacktrace_level(char *sname)
|
||||
{
|
||||
int maxbacktrace = 0;
|
||||
|
||||
if (sourcing_name != NULL) {
|
||||
char *p = sourcing_name;
|
||||
if (sname != NULL) {
|
||||
char *p = sname;
|
||||
char *q;
|
||||
while ((q = strstr(p, "..")) != NULL) {
|
||||
p = q + 2;
|
||||
@ -320,20 +324,24 @@ static void do_checkbacktracelevel(void)
|
||||
debug_backtrace_level = 0;
|
||||
msg(_("frame is zero"));
|
||||
} else {
|
||||
int max = get_maxbacktrace_level();
|
||||
char *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);
|
||||
}
|
||||
xfree(sname);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_showbacktrace(char_u *cmd)
|
||||
{
|
||||
if (sourcing_name != NULL) {
|
||||
char *sname = estack_sfile();
|
||||
int max = get_maxbacktrace_level(sname);
|
||||
if (sname != NULL) {
|
||||
int i = 0;
|
||||
int max = get_maxbacktrace_level();
|
||||
char *cur = sourcing_name;
|
||||
char *cur = sname;
|
||||
while (!got_int) {
|
||||
char *next = strstr(cur, "..");
|
||||
if (next != NULL) {
|
||||
@ -351,9 +359,11 @@ static void do_showbacktrace(char_u *cmd)
|
||||
*next = '.';
|
||||
cur = next + 2;
|
||||
}
|
||||
xfree(sname);
|
||||
}
|
||||
if (sourcing_lnum != 0) {
|
||||
smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmd);
|
||||
|
||||
if (SOURCING_LNUM != 0) {
|
||||
smsg(_("line %" PRId64 ": %s"), (int64_t)SOURCING_LNUM, cmd);
|
||||
} else {
|
||||
smsg(_("cmd: %s"), cmd);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "nvim/profile.h"
|
||||
#include "nvim/quickfix.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/search.h"
|
||||
#include "nvim/sign.h"
|
||||
@ -8613,8 +8614,8 @@ typval_T eval_call_provider(char *provider, char *method, list_T *arguments, boo
|
||||
struct caller_scope saved_provider_caller_scope = provider_caller_scope;
|
||||
provider_caller_scope = (struct caller_scope) {
|
||||
.script_ctx = current_sctx,
|
||||
.sourcing_name = sourcing_name,
|
||||
.sourcing_lnum = sourcing_lnum,
|
||||
.sourcing_name = SOURCING_NAME,
|
||||
.sourcing_lnum = SOURCING_LNUM,
|
||||
.autocmd_fname = autocmd_fname,
|
||||
.autocmd_match = autocmd_match,
|
||||
.autocmd_bufnr = autocmd_bufnr,
|
||||
@ -8713,8 +8714,8 @@ bool eval_has_provider(const char *feat)
|
||||
/// Writes "<sourcing_name>:<sourcing_lnum>" to `buf[bufsize]`.
|
||||
void eval_fmt_source_name_line(char *buf, size_t bufsize)
|
||||
{
|
||||
if (sourcing_name) {
|
||||
snprintf(buf, bufsize, "%s:%" PRIdLINENR, sourcing_name, sourcing_lnum);
|
||||
if (SOURCING_NAME) {
|
||||
snprintf(buf, bufsize, "%s:%" PRIdLINENR, SOURCING_NAME, SOURCING_LNUM);
|
||||
} else {
|
||||
snprintf(buf, bufsize, "?");
|
||||
}
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "nvim/profile.h"
|
||||
#include "nvim/quickfix.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/search.h"
|
||||
#include "nvim/sha256.h"
|
||||
@ -7292,6 +7293,7 @@ static void f_rpcnotify(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
/// "rpcrequest()" function
|
||||
static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
{
|
||||
#if 0 // TODO:
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
const int l_provider_call_nesting = provider_call_nesting;
|
||||
@ -7385,6 +7387,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
end:
|
||||
arena_mem_free(res_mem, NULL);
|
||||
api_clear_error(&err);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// "rpcstart()" function (DEPRECATED)
|
||||
|
@ -355,6 +355,8 @@ struct ufunc {
|
||||
///< 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[]; ///< Name of function (actual size equals name);
|
||||
///< can start with <SNR>123_
|
||||
///< (<SNR> is K_SPECIAL KS_EXTRA KE_SNR)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "nvim/os/input.h"
|
||||
#include "nvim/profile.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/search.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/vim.h"
|
||||
@ -219,6 +220,17 @@ char_u *get_lambda_name(void)
|
||||
return name;
|
||||
}
|
||||
|
||||
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 = xmalloc(STRLEN(name) + 3);
|
||||
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}.
|
||||
@ -297,7 +309,7 @@ int get_lambda_tv(char **arg, typval_T *rettv, bool evaluate)
|
||||
}
|
||||
|
||||
fp->uf_refcount = 1;
|
||||
STRCPY(fp->uf_name, name);
|
||||
set_ufunc_name(fp, name);
|
||||
hash_add(&func_hashtab, UF2HIKEY(fp));
|
||||
fp->uf_args = newargs;
|
||||
ga_init(&fp->uf_def_args, (int)sizeof(char_u *), 1);
|
||||
@ -319,7 +331,7 @@ int get_lambda_tv(char **arg, typval_T *rettv, bool evaluate)
|
||||
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;
|
||||
fp->uf_script_ctx.sc_lnum += SOURCING_LNUM - newlines.ga_len;
|
||||
|
||||
pt->pt_func = fp;
|
||||
pt->pt_refcount = 1;
|
||||
@ -744,6 +756,7 @@ static void func_clear_items(ufunc_T *fp)
|
||||
ga_clear_strings(&(fp->uf_args));
|
||||
ga_clear_strings(&(fp->uf_def_args));
|
||||
ga_clear_strings(&(fp->uf_lines));
|
||||
XFREE_CLEAR(fp->uf_name_exp);
|
||||
|
||||
if (fp->uf_cb_free != NULL) {
|
||||
fp->uf_cb_free(fp->uf_cb_state);
|
||||
@ -807,8 +820,6 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
|
||||
linenr_T firstline, linenr_T lastline, dict_T *selfdict)
|
||||
FUNC_ATTR_NONNULL_ARG(1, 3, 4)
|
||||
{
|
||||
char_u *save_sourcing_name;
|
||||
linenr_T save_sourcing_lnum;
|
||||
bool using_sandbox = false;
|
||||
funccall_T *fc;
|
||||
int save_did_emsg;
|
||||
@ -998,73 +1009,49 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
|
||||
|
||||
// Don't redraw while executing the function.
|
||||
RedrawingDisabled++;
|
||||
save_sourcing_name = (char_u *)sourcing_name;
|
||||
save_sourcing_lnum = sourcing_lnum;
|
||||
sourcing_lnum = 1;
|
||||
|
||||
if (fp->uf_flags & FC_SANDBOX) {
|
||||
using_sandbox = true;
|
||||
sandbox++;
|
||||
}
|
||||
|
||||
// need space for new sourcing_name:
|
||||
// * save_sourcing_name
|
||||
// * "["number"].." or "function "
|
||||
// * "<SNR>" + fp->uf_name - 3
|
||||
// * terminating NUL
|
||||
size_t len = (save_sourcing_name == NULL ? 0 : STRLEN(save_sourcing_name))
|
||||
+ STRLEN(fp->uf_name) + 27;
|
||||
sourcing_name = xmalloc(len);
|
||||
{
|
||||
if (save_sourcing_name != NULL
|
||||
&& STRNCMP(save_sourcing_name, "function ", 9) == 0) {
|
||||
vim_snprintf(sourcing_name,
|
||||
len,
|
||||
"%s[%" PRId64 "]..",
|
||||
save_sourcing_name,
|
||||
(int64_t)save_sourcing_lnum);
|
||||
} else {
|
||||
STRCPY(sourcing_name, "function ");
|
||||
}
|
||||
cat_func_name((char_u *)sourcing_name + STRLEN(sourcing_name), fp);
|
||||
estack_push_ufunc(ETYPE_UFUNC, fp, 1);
|
||||
if (p_verbose >= 12) {
|
||||
++no_wait_return;
|
||||
verbose_enter_scroll();
|
||||
|
||||
if (p_verbose >= 12) {
|
||||
++no_wait_return;
|
||||
verbose_enter_scroll();
|
||||
|
||||
smsg(_("calling %s"), sourcing_name);
|
||||
if (p_verbose >= 14) {
|
||||
msg_puts("(");
|
||||
for (int 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++;
|
||||
char *tofree = encode_tv2string(&argvars[i], NULL);
|
||||
emsg_off--;
|
||||
if (tofree != NULL) {
|
||||
char *s = tofree;
|
||||
char buf[MSG_BUF_LEN];
|
||||
if (vim_strsize(s) > MSG_BUF_CLEN) {
|
||||
trunc_string(s, buf, MSG_BUF_CLEN, sizeof(buf));
|
||||
s = buf;
|
||||
}
|
||||
msg_puts(s);
|
||||
xfree(tofree);
|
||||
smsg(_("calling %s"), SOURCING_NAME);
|
||||
if (p_verbose >= 14) {
|
||||
msg_puts("(");
|
||||
for (int 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++;
|
||||
char *tofree = encode_tv2string(&argvars[i], NULL);
|
||||
emsg_off--;
|
||||
if (tofree != NULL) {
|
||||
char *s = tofree;
|
||||
char buf[MSG_BUF_LEN];
|
||||
if (vim_strsize(s) > MSG_BUF_CLEN) {
|
||||
trunc_string(s, buf, MSG_BUF_CLEN, sizeof(buf));
|
||||
s = buf;
|
||||
}
|
||||
msg_puts(s);
|
||||
xfree(tofree);
|
||||
}
|
||||
}
|
||||
msg_puts(")");
|
||||
}
|
||||
msg_puts("\n"); // don't overwrite this either
|
||||
|
||||
verbose_leave_scroll();
|
||||
--no_wait_return;
|
||||
msg_puts(")");
|
||||
}
|
||||
msg_puts("\n"); // don't overwrite this either
|
||||
|
||||
verbose_leave_scroll();
|
||||
--no_wait_return;
|
||||
}
|
||||
|
||||
const bool do_profiling_yes = do_profiling == PROF_YES;
|
||||
@ -1148,10 +1135,10 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
|
||||
verbose_enter_scroll();
|
||||
|
||||
if (aborting()) {
|
||||
smsg(_("%s aborted"), sourcing_name);
|
||||
smsg(_("%s aborted"), SOURCING_NAME);
|
||||
} else if (fc->rettv->v_type == VAR_NUMBER) {
|
||||
smsg(_("%s returning #%" PRId64 ""),
|
||||
sourcing_name, (int64_t)fc->rettv->vval.v_number);
|
||||
SOURCING_NAME, (int64_t)fc->rettv->vval.v_number);
|
||||
} else {
|
||||
char buf[MSG_BUF_LEN];
|
||||
|
||||
@ -1167,7 +1154,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
|
||||
trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN);
|
||||
s = buf;
|
||||
}
|
||||
smsg(_("%s returning %s"), sourcing_name, s);
|
||||
smsg(_("%s returning %s"), SOURCING_NAME, s);
|
||||
xfree(tofree);
|
||||
}
|
||||
}
|
||||
@ -1177,9 +1164,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
|
||||
--no_wait_return;
|
||||
}
|
||||
|
||||
xfree(sourcing_name);
|
||||
sourcing_name = (char *)save_sourcing_name;
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
estack_pop();
|
||||
current_sctx = save_current_sctx;
|
||||
if (do_profiling_yes) {
|
||||
script_prof_restore(&wait_start);
|
||||
@ -1188,15 +1173,15 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
|
||||
sandbox--;
|
||||
}
|
||||
|
||||
if (p_verbose >= 12 && sourcing_name != NULL) {
|
||||
++no_wait_return;
|
||||
if (p_verbose >= 12 && SOURCING_NAME != NULL) {
|
||||
no_wait_return++;
|
||||
verbose_enter_scroll();
|
||||
|
||||
smsg(_("continuing in %s"), sourcing_name);
|
||||
smsg(_("continuing in %s"), SOURCING_NAME);
|
||||
msg_puts("\n"); // don't overwrite this either
|
||||
|
||||
verbose_leave_scroll();
|
||||
--no_wait_return;
|
||||
no_wait_return--;
|
||||
}
|
||||
|
||||
did_emsg |= save_did_emsg;
|
||||
@ -1637,9 +1622,8 @@ static void list_func_head(ufunc_T *fp, int indent, bool force)
|
||||
msg_puts(" ");
|
||||
}
|
||||
msg_puts(force ? "function! " : "function ");
|
||||
if (fp->uf_name[0] == K_SPECIAL) {
|
||||
msg_puts_attr("<SNR>", HL_ATTR(HLF_8));
|
||||
msg_puts((const char *)fp->uf_name + 3);
|
||||
if (fp->uf_name_exp != NULL) {
|
||||
msg_puts((const char *)fp->uf_name_exp);
|
||||
} else {
|
||||
msg_puts((const char *)fp->uf_name);
|
||||
}
|
||||
@ -2196,7 +2180,7 @@ void ex_function(exarg_T *eap)
|
||||
}
|
||||
|
||||
// Save the starting line number.
|
||||
sourcing_lnum_top = sourcing_lnum;
|
||||
sourcing_lnum_top = SOURCING_LNUM;
|
||||
|
||||
indent = 2;
|
||||
nesting = 0;
|
||||
@ -2238,10 +2222,10 @@ void ex_function(exarg_T *eap)
|
||||
ui_ext_cmdline_block_append((size_t)indent, (const char *)theline);
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (sourcing_lnum < sourcing_lnum_off) {
|
||||
sourcing_lnum_off -= sourcing_lnum;
|
||||
if (SOURCING_LNUM < sourcing_lnum_off) {
|
||||
sourcing_lnum_off -= SOURCING_LNUM;
|
||||
} else {
|
||||
sourcing_lnum_off = 0;
|
||||
}
|
||||
@ -2499,13 +2483,12 @@ void ex_function(exarg_T *eap)
|
||||
|
||||
// Check that the autoload name matches the script name.
|
||||
int j = FAIL;
|
||||
if (sourcing_name != NULL) {
|
||||
if (SOURCING_NAME != NULL) {
|
||||
scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name));
|
||||
p = (char_u *)vim_strchr((char *)scriptname, '/');
|
||||
plen = (int)STRLEN(p);
|
||||
slen = (int)STRLEN(sourcing_name);
|
||||
if (slen > plen && FNAMECMP(p,
|
||||
sourcing_name + slen - plen) == 0) {
|
||||
slen = (int)STRLEN(SOURCING_NAME);
|
||||
if (slen > plen && FNAMECMP(p, SOURCING_NAME + slen - plen) == 0) {
|
||||
j = OK;
|
||||
}
|
||||
xfree(scriptname);
|
||||
@ -2540,7 +2523,7 @@ void ex_function(exarg_T *eap)
|
||||
}
|
||||
|
||||
// insert the new function in the function list
|
||||
STRCPY(fp->uf_name, name);
|
||||
set_ufunc_name(fp, name);
|
||||
if (overwrite) {
|
||||
hi = hash_find(&func_hashtab, (char *)name);
|
||||
hi->hi_key = UF2HIKEY(fp);
|
||||
@ -3148,8 +3131,7 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat)
|
||||
|
||||
// If breakpoints have been added/deleted need to check for it.
|
||||
if (fcp->dbg_tick != debug_tick) {
|
||||
fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
|
||||
sourcing_lnum);
|
||||
fcp->breakpoint = dbg_find_breakpoint(false, fp->uf_name, SOURCING_LNUM);
|
||||
fcp->dbg_tick = debug_tick;
|
||||
}
|
||||
if (do_profiling == PROF_YES) {
|
||||
@ -3170,7 +3152,7 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat)
|
||||
retval = NULL;
|
||||
} else {
|
||||
retval = (char_u *)xstrdup(((char **)(gap->ga_data))[fcp->linenr++]);
|
||||
sourcing_lnum = fcp->linenr;
|
||||
SOURCING_LNUM = fcp->linenr;
|
||||
if (do_profiling == PROF_YES) {
|
||||
func_line_start(cookie);
|
||||
}
|
||||
@ -3178,11 +3160,10 @@ char *get_func_line(int c, void *cookie, int indent, bool do_concat)
|
||||
}
|
||||
|
||||
// Did we encounter a breakpoint?
|
||||
if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) {
|
||||
dbg_breakpoint(fp->uf_name, sourcing_lnum);
|
||||
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->breakpoint = dbg_find_breakpoint(false, fp->uf_name, SOURCING_LNUM);
|
||||
fcp->dbg_tick = debug_tick;
|
||||
}
|
||||
|
||||
|
@ -373,7 +373,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
||||
breakpoint = func_breakpoint(real_cookie);
|
||||
dbg_tick = func_dbg_tick(real_cookie);
|
||||
} else if (getline_equal(fgetline, cookie, getsourceline)) {
|
||||
fname = sourcing_name;
|
||||
fname = SOURCING_NAME;
|
||||
breakpoint = source_breakpoint(real_cookie);
|
||||
dbg_tick = source_dbg_tick(real_cookie);
|
||||
}
|
||||
@ -466,20 +466,19 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
||||
if (breakpoint != NULL && dbg_tick != NULL
|
||||
&& *dbg_tick != debug_tick) {
|
||||
*breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
|
||||
(char_u *)fname, sourcing_lnum);
|
||||
(char_u *)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;
|
||||
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((char_u *)fname, sourcing_lnum);
|
||||
if (breakpoint != NULL && *breakpoint != 0 && *breakpoint <= SOURCING_LNUM) {
|
||||
dbg_breakpoint((char_u *)fname, SOURCING_LNUM);
|
||||
// Find next breakpoint.
|
||||
*breakpoint = dbg_find_breakpoint(getline_equal(fgetline, cookie, getsourceline),
|
||||
(char_u *)fname, sourcing_lnum);
|
||||
(char_u *)fname, SOURCING_LNUM);
|
||||
*dbg_tick = debug_tick;
|
||||
}
|
||||
if (do_profiling == PROF_YES) {
|
||||
@ -582,8 +581,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
if ((p_verbose >= 15 && sourcing_name != NULL) || p_verbose >= 16) {
|
||||
msg_verbose_cmd(sourcing_lnum, cmdline_copy);
|
||||
if ((p_verbose >= 15 && SOURCING_NAME != NULL) || p_verbose >= 16) {
|
||||
msg_verbose_cmd(SOURCING_LNUM, cmdline_copy);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -683,7 +682,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
||||
*/
|
||||
if (cstack.cs_looplevel == 0) {
|
||||
if (!GA_EMPTY(&lines_ga)) {
|
||||
sourcing_lnum = ((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
|
||||
SOURCING_LNUM = ((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
|
||||
GA_DEEP_CLEAR(&lines_ga, wcmd_T, FREE_WCMD);
|
||||
}
|
||||
current_line = 0;
|
||||
@ -800,8 +799,6 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
||||
// commands are executed.
|
||||
if (current_exception) {
|
||||
char *p = NULL;
|
||||
char *saved_sourcing_name;
|
||||
linenr_T saved_sourcing_lnum;
|
||||
msglist_T *messages = NULL;
|
||||
msglist_T *next;
|
||||
|
||||
@ -826,10 +823,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
||||
break;
|
||||
}
|
||||
|
||||
saved_sourcing_name = sourcing_name;
|
||||
saved_sourcing_lnum = sourcing_lnum;
|
||||
sourcing_name = current_exception->throw_name;
|
||||
sourcing_lnum = current_exception->throw_lnum;
|
||||
estack_push(ETYPE_EXCEPT, current_exception->throw_name, current_exception->throw_lnum);
|
||||
current_exception->throw_name = NULL;
|
||||
|
||||
discard_current_exception(); // uses IObuff if 'verbose'
|
||||
@ -849,9 +843,8 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags)
|
||||
emsg(p);
|
||||
xfree(p);
|
||||
}
|
||||
xfree(sourcing_name);
|
||||
sourcing_name = saved_sourcing_name;
|
||||
sourcing_lnum = saved_sourcing_lnum;
|
||||
xfree(SOURCING_NAME);
|
||||
estack_pop();
|
||||
} else if (got_int || (did_emsg && force_abort)) {
|
||||
// On an interrupt or an aborting error not converted to an exception,
|
||||
// disable the conversion of errors to exceptions. (Interrupts are not
|
||||
@ -979,7 +972,7 @@ static char *get_loop_line(int c, void *cookie, int indent, bool do_concat)
|
||||
KeyTyped = false;
|
||||
cp->current_line++;
|
||||
wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line;
|
||||
sourcing_lnum = wp->lnum;
|
||||
SOURCING_LNUM = wp->lnum;
|
||||
return xstrdup(wp->line);
|
||||
}
|
||||
|
||||
@ -988,7 +981,7 @@ static void store_loop_line(garray_T *gap, char *line)
|
||||
{
|
||||
wcmd_T *p = GA_APPEND_VIA_PTR(wcmd_T, gap);
|
||||
p->line = xstrdup(line);
|
||||
p->lnum = sourcing_lnum;
|
||||
p->lnum = SOURCING_LNUM;
|
||||
}
|
||||
|
||||
/// If "fgetline" is get_loop_line(), return TRUE if the getline it uses equals
|
||||
@ -7919,29 +7912,30 @@ char_u *eval_vars(char_u *src, char_u *srcstart, size_t *usedlen, linenr_T *lnum
|
||||
break;
|
||||
|
||||
case SPEC_SFILE: // file name for ":so" command
|
||||
result = sourcing_name;
|
||||
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) {
|
||||
if (SOURCING_NAME == NULL || SOURCING_LNUM == 0) {
|
||||
*errormsg = _("E842: no line number to use for \"<slnum>\"");
|
||||
return NULL;
|
||||
}
|
||||
snprintf(strbuf, sizeof(strbuf), "%" PRIdLINENR, sourcing_lnum);
|
||||
snprintf(strbuf, sizeof(strbuf), "%" PRIdLINENR, SOURCING_LNUM);
|
||||
result = strbuf;
|
||||
break;
|
||||
|
||||
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>\"");
|
||||
return NULL;
|
||||
}
|
||||
snprintf((char *)strbuf, sizeof(strbuf), "%" PRIdLINENR,
|
||||
current_sctx.sc_lnum + sourcing_lnum);
|
||||
current_sctx.sc_lnum + SOURCING_LNUM);
|
||||
result = strbuf;
|
||||
break;
|
||||
|
||||
|
@ -478,8 +478,11 @@ static int throw_exception(void *value, except_type_T type, char *cmdname)
|
||||
}
|
||||
|
||||
excp->type = type;
|
||||
excp->throw_name = xstrdup(sourcing_name == NULL ? "" : sourcing_name);
|
||||
excp->throw_lnum = sourcing_lnum;
|
||||
excp->throw_name = estack_sfile();
|
||||
if (excp->throw_name == NULL) {
|
||||
excp->throw_name = xstrdup("");
|
||||
}
|
||||
excp->throw_lnum = SOURCING_LNUM;
|
||||
|
||||
if (p_verbose >= 13 || debug_break_level > 0) {
|
||||
int save_msg_silent = msg_silent;
|
||||
|
@ -248,9 +248,6 @@ EXTERN int lines_left INIT(= -1); // lines left for listing
|
||||
EXTERN int msg_no_more INIT(= false); // don't use more prompt, truncate
|
||||
// messages
|
||||
|
||||
EXTERN char *sourcing_name INIT(= NULL); // name of error message source
|
||||
EXTERN linenr_T sourcing_lnum INIT(= 0); // line number of the source file
|
||||
|
||||
EXTERN int ex_nesting_level INIT(= 0); // nesting level
|
||||
EXTERN int debug_break_level INIT(= -1); // break below this level
|
||||
EXTERN bool debug_did_msg INIT(= false); // did "debug mode" message
|
||||
|
@ -691,12 +691,12 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
|
||||
g->sg_cleared = false;
|
||||
g->sg_link = link_id;
|
||||
g->sg_script_ctx = current_sctx;
|
||||
g->sg_script_ctx.sc_lnum += sourcing_lnum;
|
||||
g->sg_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||
g->sg_set |= SG_LINK;
|
||||
if (is_default) {
|
||||
g->sg_deflink = link_id;
|
||||
g->sg_deflink_sctx = current_sctx;
|
||||
g->sg_deflink_sctx.sc_lnum += sourcing_lnum;
|
||||
g->sg_deflink_sctx.sc_lnum += SOURCING_LNUM;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -735,7 +735,7 @@ void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
|
||||
g->sg_blend = attrs.hl_blend;
|
||||
|
||||
g->sg_script_ctx = current_sctx;
|
||||
g->sg_script_ctx.sc_lnum += sourcing_lnum;
|
||||
g->sg_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||
|
||||
g->sg_attr = hl_get_syn_attr(0, id, attrs);
|
||||
|
||||
@ -863,7 +863,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
|
||||
if (dodefault && (forceit || hlgroup->sg_deflink == 0)) {
|
||||
hlgroup->sg_deflink = to_id;
|
||||
hlgroup->sg_deflink_sctx = current_sctx;
|
||||
hlgroup->sg_deflink_sctx.sc_lnum += sourcing_lnum;
|
||||
hlgroup->sg_deflink_sctx.sc_lnum += SOURCING_LNUM;
|
||||
nlua_set_sctx(&hlgroup->sg_deflink_sctx);
|
||||
}
|
||||
}
|
||||
@ -873,7 +873,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
|
||||
// for the group, unless '!' is used
|
||||
if (to_id > 0 && !forceit && !init
|
||||
&& 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"));
|
||||
}
|
||||
} else if (hlgroup->sg_link != to_id
|
||||
@ -884,7 +884,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
|
||||
}
|
||||
hlgroup->sg_link = to_id;
|
||||
hlgroup->sg_script_ctx = current_sctx;
|
||||
hlgroup->sg_script_ctx.sc_lnum += sourcing_lnum;
|
||||
hlgroup->sg_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||
nlua_set_sctx(&hlgroup->sg_script_ctx);
|
||||
hlgroup->sg_cleared = false;
|
||||
redraw_all_later(SOME_VALID);
|
||||
@ -1274,7 +1274,7 @@ void do_highlight(const char *line, const bool forceit, const bool init)
|
||||
set_hl_attr(idx);
|
||||
}
|
||||
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;
|
||||
nlua_set_sctx(&hl_table[idx].sg_script_ctx);
|
||||
|
||||
// Only call highlight_changed() once, after a sequence of highlight
|
||||
|
@ -1313,6 +1313,7 @@ static void nlua_typval_exec(const char *lcmd, size_t lcmd_len, const char *name
|
||||
|
||||
int nlua_source_using_linegetter(LineGetter fgetline, void *cookie, char *name)
|
||||
{
|
||||
#if 0 // TODO:
|
||||
const linenr_T save_sourcing_lnum = sourcing_lnum;
|
||||
const sctx_T save_current_sctx = current_sctx;
|
||||
current_sctx.sc_sid = SID_STR;
|
||||
@ -1336,6 +1337,7 @@ int nlua_source_using_linegetter(LineGetter fgetline, void *cookie, char *name)
|
||||
ga_clear_strings(&ga);
|
||||
xfree(code);
|
||||
return OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Call a LuaCallable given some typvals
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "nvim/popupmnu.h"
|
||||
#include "nvim/profile.h"
|
||||
#include "nvim/quickfix.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/shada.h"
|
||||
#include "nvim/sign.h"
|
||||
@ -159,6 +160,7 @@ bool event_teardown(void)
|
||||
void early_init(mparm_T *paramp)
|
||||
{
|
||||
env_init();
|
||||
estack_init();
|
||||
cmdline_init();
|
||||
eval_init(); // init global variables
|
||||
init_path(argv0 ? argv0 : "nvim");
|
||||
@ -1814,12 +1816,12 @@ static void exe_pre_commands(mparm_T *parmp)
|
||||
|
||||
if (cnt > 0) {
|
||||
curwin->w_cursor.lnum = 0; // just in case..
|
||||
sourcing_name = _("pre-vimrc command line");
|
||||
estack_push(ETYPE_ARGS, _("pre-vimrc command line"), 0);
|
||||
current_sctx.sc_sid = SID_CMDARG;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
do_cmdline_cmd(cmds[i]);
|
||||
}
|
||||
sourcing_name = NULL;
|
||||
estack_pop();
|
||||
current_sctx.sc_sid = 0;
|
||||
TIME_MSG("--cmd commands");
|
||||
}
|
||||
@ -1841,7 +1843,7 @@ static void exe_commands(mparm_T *parmp)
|
||||
if (parmp->tagname == NULL && curwin->w_cursor.lnum <= 1) {
|
||||
curwin->w_cursor.lnum = 0;
|
||||
}
|
||||
sourcing_name = "command line";
|
||||
estack_push(ETYPE_ARGS, "command line", 0);
|
||||
current_sctx.sc_sid = SID_CARG;
|
||||
current_sctx.sc_seq = 0;
|
||||
for (i = 0; i < parmp->n_commands; i++) {
|
||||
@ -1850,7 +1852,7 @@ static void exe_commands(mparm_T *parmp)
|
||||
xfree(parmp->commands[i]);
|
||||
}
|
||||
}
|
||||
sourcing_name = NULL;
|
||||
estack_pop();
|
||||
current_sctx.sc_sid = 0;
|
||||
if (curwin->w_cursor.lnum == 0) {
|
||||
curwin->w_cursor.lnum = 1;
|
||||
@ -2059,17 +2061,14 @@ static int execute_env(char *env)
|
||||
{
|
||||
const char *initstr = os_getenv(env);
|
||||
if (initstr != NULL) {
|
||||
char_u *save_sourcing_name = (char_u *)sourcing_name;
|
||||
linenr_T save_sourcing_lnum = sourcing_lnum;
|
||||
sourcing_name = env;
|
||||
sourcing_lnum = 0;
|
||||
estack_push(ETYPE_ENV, env, 0);
|
||||
const sctx_T save_current_sctx = current_sctx;
|
||||
current_sctx.sc_sid = SID_ENV;
|
||||
current_sctx.sc_seq = 0;
|
||||
current_sctx.sc_lnum = 0;
|
||||
do_cmdline_cmd((char *)initstr);
|
||||
sourcing_name = (char *)save_sourcing_name;
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
|
||||
estack_pop();
|
||||
current_sctx = save_current_sctx;
|
||||
return OK;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "nvim/message.h"
|
||||
#include "nvim/option.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/vim.h"
|
||||
|
||||
@ -469,7 +470,7 @@ static void map_add(buf_T *buf, mapblock_T **map_table, mapblock_T **abbr_table,
|
||||
mp->m_script_ctx.sc_lnum = lnum;
|
||||
} else {
|
||||
mp->m_script_ctx = current_sctx;
|
||||
mp->m_script_ctx.sc_lnum += sourcing_lnum;
|
||||
mp->m_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||
nlua_set_sctx(&mp->m_script_ctx);
|
||||
}
|
||||
mp->m_desc = NULL;
|
||||
@ -776,7 +777,7 @@ static int buf_do_map(int maptype, MapArguments *args, int mode, bool is_abbrev,
|
||||
mp->m_expr = args->expr;
|
||||
mp->m_replace_keycodes = args->replace_keycodes;
|
||||
mp->m_script_ctx = current_sctx;
|
||||
mp->m_script_ctx.sc_lnum += sourcing_lnum;
|
||||
mp->m_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||
nlua_set_sctx(&mp->m_script_ctx);
|
||||
if (args->desc != NULL) {
|
||||
mp->m_desc = xstrdup(args->desc);
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "nvim/os/os.h"
|
||||
#include "nvim/os/time.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/strings.h"
|
||||
#include "nvim/syntax.h"
|
||||
@ -524,7 +525,7 @@ int smsg_attr_keep(int attr, const char *s, ...)
|
||||
* isn't printed each time when it didn't change.
|
||||
*/
|
||||
static int last_sourcing_lnum = 0;
|
||||
static char_u *last_sourcing_name = NULL;
|
||||
static char *last_sourcing_name = NULL;
|
||||
|
||||
/// Reset the last used sourcing name/lnum. Makes sure it is displayed again
|
||||
/// for the next error message;
|
||||
@ -534,16 +535,16 @@ void reset_last_sourcing(void)
|
||||
last_sourcing_lnum = 0;
|
||||
}
|
||||
|
||||
/// @return TRUE if "sourcing_name" differs from "last_sourcing_name".
|
||||
static int other_sourcing_name(void)
|
||||
/// @return true if "SOURCING_NAME" differs from "last_sourcing_name".
|
||||
static bool other_sourcing_name(void)
|
||||
{
|
||||
if (sourcing_name != NULL) {
|
||||
if (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;
|
||||
}
|
||||
|
||||
/// Get the message about the source, as used for an error message
|
||||
@ -553,11 +554,19 @@ static int other_sourcing_name(void)
|
||||
static char *get_emsg_source(void)
|
||||
FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (sourcing_name != NULL && other_sourcing_name()) {
|
||||
if (SOURCING_NAME != NULL && other_sourcing_name()) {
|
||||
char *sname = estack_sfile();
|
||||
char *tofree = sname;
|
||||
|
||||
if (sname == NULL) {
|
||||
sname = SOURCING_NAME;
|
||||
}
|
||||
|
||||
const char *const p = _("Error detected while processing %s:");
|
||||
const size_t buf_len = STRLEN(sourcing_name) + strlen(p) + 1;
|
||||
const size_t buf_len = STRLEN(sname) + strlen(p) + 1;
|
||||
char *const buf = xmalloc(buf_len);
|
||||
snprintf(buf, buf_len, p, sourcing_name);
|
||||
snprintf(buf, buf_len, p, sname);
|
||||
xfree(tofree);
|
||||
return buf;
|
||||
}
|
||||
return NULL;
|
||||
@ -572,13 +581,13 @@ static char *get_emsg_lnum(void)
|
||||
{
|
||||
// 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) {
|
||||
if (SOURCING_NAME != NULL
|
||||
&& (other_sourcing_name() || SOURCING_LNUM != last_sourcing_lnum)
|
||||
&& SOURCING_LNUM != 0) {
|
||||
const char *const p = _("line %4ld:");
|
||||
const size_t buf_len = 20 + strlen(p);
|
||||
char *const buf = xmalloc(buf_len);
|
||||
snprintf(buf, buf_len, p, (long)sourcing_lnum);
|
||||
snprintf(buf, buf_len, p, (long)SOURCING_LNUM);
|
||||
return buf;
|
||||
}
|
||||
return NULL;
|
||||
@ -599,16 +608,16 @@ void msg_source(int attr)
|
||||
if (p != NULL) {
|
||||
msg_attr(p, HL_ATTR(HLF_N));
|
||||
xfree(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
|
||||
if (sourcing_name == NULL || other_sourcing_name()) {
|
||||
if (SOURCING_NAME == NULL || other_sourcing_name()) {
|
||||
xfree(last_sourcing_name);
|
||||
if (sourcing_name == NULL) {
|
||||
if (SOURCING_NAME == NULL) {
|
||||
last_sourcing_name = NULL;
|
||||
} else {
|
||||
last_sourcing_name = vim_strsave((char_u *)sourcing_name);
|
||||
last_sourcing_name = xstrdup(SOURCING_NAME);
|
||||
}
|
||||
}
|
||||
--no_wait_return;
|
||||
@ -686,9 +695,9 @@ static bool emsg_multiline(const char *s, bool multiline)
|
||||
}
|
||||
|
||||
// Log (silent) errors as debug messages.
|
||||
if (sourcing_name != NULL && sourcing_lnum != 0) {
|
||||
if (SOURCING_NAME != NULL && SOURCING_LNUM != 0) {
|
||||
DLOG("(:silent) %s (%s (line %ld))",
|
||||
s, sourcing_name, (long)sourcing_lnum);
|
||||
s, SOURCING_NAME, (long)SOURCING_LNUM);
|
||||
} else {
|
||||
DLOG("(:silent) %s", s);
|
||||
}
|
||||
@ -697,8 +706,8 @@ static bool emsg_multiline(const char *s, bool multiline)
|
||||
}
|
||||
|
||||
// Log editor errors as INFO.
|
||||
if (sourcing_name != NULL && sourcing_lnum != 0) {
|
||||
ILOG("%s (%s (line %ld))", s, sourcing_name, (long)sourcing_lnum);
|
||||
if (SOURCING_NAME != NULL && SOURCING_LNUM != 0) {
|
||||
ILOG("%s (%s (line %ld))", s, SOURCING_NAME, (long)SOURCING_LNUM);
|
||||
} else {
|
||||
ILOG("%s", s);
|
||||
}
|
||||
@ -2457,7 +2466,7 @@ void msg_reset_scroll(void)
|
||||
static void inc_msg_scrolled(void)
|
||||
{
|
||||
if (*get_vim_var_str(VV_SCROLLSTART) == NUL) {
|
||||
char *p = sourcing_name;
|
||||
char *p = SOURCING_NAME;
|
||||
char *tofree = NULL;
|
||||
|
||||
// v:scrollstart is empty, set it to the script/function name and line
|
||||
@ -2468,7 +2477,7 @@ static void inc_msg_scrolled(void)
|
||||
size_t len = strlen(p) + 40;
|
||||
tofree = xmalloc(len);
|
||||
vim_snprintf(tofree, len, _("%s line %" PRId64),
|
||||
p, (int64_t)sourcing_lnum);
|
||||
p, (int64_t)SOURCING_LNUM);
|
||||
p = tofree;
|
||||
}
|
||||
set_vim_var_string(VV_SCROLLSTART, p, -1);
|
||||
|
@ -3996,7 +3996,7 @@ static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
|
||||
.script_ctx = {
|
||||
script_ctx.sc_sid,
|
||||
script_ctx.sc_seq,
|
||||
script_ctx.sc_lnum + sourcing_lnum
|
||||
script_ctx.sc_lnum + SOURCING_LNUM
|
||||
},
|
||||
current_channel_id
|
||||
};
|
||||
|
@ -532,9 +532,8 @@ void func_line_start(void *cookie)
|
||||
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;
|
||||
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--;
|
||||
@ -798,11 +797,11 @@ void script_line_start(void)
|
||||
return;
|
||||
}
|
||||
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
|
||||
// here isn't counted.
|
||||
(void)ga_grow(&si->sn_prl_ga, sourcing_lnum - si->sn_prl_ga.ga_len);
|
||||
si->sn_prl_idx = sourcing_lnum - 1;
|
||||
(void)ga_grow(&si->sn_prl_ga, 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) {
|
||||
// Zero counters for a line that was not used before.
|
||||
|
@ -50,8 +50,94 @@ struct source_cookie {
|
||||
# include "runtime.c.generated.h"
|
||||
#endif
|
||||
|
||||
garray_T exestack = { 0, 0, sizeof(estack_T), 50, NULL };
|
||||
garray_T script_items = { 0, 0, sizeof(scriptitem_T), 4, NULL };
|
||||
|
||||
/// Initialize the execution stack.
|
||||
void estack_init(void)
|
||||
{
|
||||
ga_grow(&exestack, 10);
|
||||
estack_T *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.
|
||||
/// @return the new entry
|
||||
estack_T *estack_push(etype_T type, char *name, linenr_T lnum)
|
||||
{
|
||||
ga_grow(&exestack, 1);
|
||||
estack_T *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;
|
||||
}
|
||||
|
||||
/// Add a user function to the execution stack.
|
||||
void estack_push_ufunc(etype_T type, ufunc_T *ufunc, linenr_T lnum)
|
||||
{
|
||||
estack_T *entry = estack_push(type,
|
||||
(char *)(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 *estack_sfile(void)
|
||||
{
|
||||
estack_T *entry = ((estack_T *)exestack.ga_data) + exestack.ga_len - 1;
|
||||
if (entry->es_name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (entry->es_info.ufunc == NULL) {
|
||||
return xstrdup(entry->es_name);
|
||||
}
|
||||
|
||||
// For a function we compose the call stack, as it was done in the past:
|
||||
// "function One[123]..Two[456]..Three"
|
||||
size_t len = STRLEN(entry->es_name) + 10;
|
||||
int idx;
|
||||
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;
|
||||
}
|
||||
|
||||
char *res = (char *)xmalloc(len);
|
||||
STRCPY(res, "function ");
|
||||
size_t done;
|
||||
while (idx < exestack.ga_len - 1) {
|
||||
done = STRLEN(res);
|
||||
entry = ((estack_T *)exestack.ga_data) + idx;
|
||||
vim_snprintf(res + done, len - done, "%s[%" PRIdLINENR "]..", 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 res;
|
||||
}
|
||||
|
||||
static bool runtime_search_path_valid = false;
|
||||
static int *runtime_search_path_ref = NULL;
|
||||
static RuntimeSearchPath runtime_search_path;
|
||||
@ -1645,6 +1731,7 @@ scriptitem_T *new_script_item(char *const name, scid_T *const sid_out)
|
||||
|
||||
static int source_using_linegetter(void *cookie, LineGetter fgetline, const char *traceback_name)
|
||||
{
|
||||
#if 0 // TODO:
|
||||
char *save_sourcing_name = sourcing_name;
|
||||
linenr_T save_sourcing_lnum = sourcing_lnum;
|
||||
char sourcing_name_buf[256];
|
||||
@ -1673,6 +1760,7 @@ static int source_using_linegetter(void *cookie, LineGetter fgetline, const char
|
||||
current_sctx = save_current_sctx;
|
||||
restore_funccal();
|
||||
return retval;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cmd_source_buffer(const exarg_T *const eap)
|
||||
@ -1736,8 +1824,6 @@ int do_source_str(const char *cmd, const char *traceback_name)
|
||||
int do_source(char *fname, int check_other, int is_vimrc)
|
||||
{
|
||||
struct source_cookie cookie;
|
||||
char *save_sourcing_name;
|
||||
linenr_T save_sourcing_lnum;
|
||||
char *p;
|
||||
char *fname_exp;
|
||||
uint8_t *firstline = NULL;
|
||||
@ -1791,11 +1877,11 @@ int do_source(char *fname, int check_other, int is_vimrc)
|
||||
if (cookie.fp == NULL) {
|
||||
if (p_verbose > 1) {
|
||||
verbose_enter();
|
||||
if (sourcing_name == NULL) {
|
||||
if (SOURCING_NAME == NULL) {
|
||||
smsg(_("could not source \"%s\""), fname);
|
||||
} else {
|
||||
smsg(_("line %" PRId64 ": could not source \"%s\""),
|
||||
(int64_t)sourcing_lnum, fname);
|
||||
(int64_t)SOURCING_LNUM, fname);
|
||||
}
|
||||
verbose_leave();
|
||||
}
|
||||
@ -1807,11 +1893,10 @@ int do_source(char *fname, int check_other, int is_vimrc)
|
||||
// - For a vimrc file, may want to call vimrc_found().
|
||||
if (p_verbose > 1) {
|
||||
verbose_enter();
|
||||
if (sourcing_name == NULL) {
|
||||
if (SOURCING_NAME == NULL) {
|
||||
smsg(_("sourcing \"%s\""), fname);
|
||||
} else {
|
||||
smsg(_("line %" PRId64 ": sourcing \"%s\""),
|
||||
(int64_t)sourcing_lnum, fname);
|
||||
smsg(_("line %" PRId64 ": sourcing \"%s\""), (int64_t)SOURCING_LNUM, fname);
|
||||
}
|
||||
verbose_leave();
|
||||
}
|
||||
@ -1841,10 +1926,7 @@ int do_source(char *fname, int check_other, int is_vimrc)
|
||||
cookie.level = ex_nesting_level;
|
||||
|
||||
// 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;
|
||||
estack_push(ETYPE_SCRIPT, fname_exp, 0);
|
||||
|
||||
// start measuring script load time if --startuptime was passed and
|
||||
// time_fd was successfully opened afterwards.
|
||||
@ -1900,6 +1982,7 @@ int do_source(char *fname, int check_other, int is_vimrc)
|
||||
}
|
||||
|
||||
if (path_with_extension((const char *)fname_exp, "lua")) {
|
||||
#if 0 // TODO:
|
||||
const sctx_T current_sctx_backup = current_sctx;
|
||||
const linenr_T sourcing_lnum_backup = sourcing_lnum;
|
||||
current_sctx.sc_sid = SID_LUA;
|
||||
@ -1909,6 +1992,7 @@ int do_source(char *fname, int check_other, int is_vimrc)
|
||||
nlua_exec_file((const char *)fname_exp);
|
||||
current_sctx = current_sctx_backup;
|
||||
sourcing_lnum = sourcing_lnum_backup;
|
||||
#endif
|
||||
} else {
|
||||
// Call do_cmdline, which will call getsourceline() to get the lines.
|
||||
do_cmdline((char *)firstline, getsourceline, (void *)&cookie,
|
||||
@ -1931,13 +2015,12 @@ int do_source(char *fname, int check_other, int is_vimrc)
|
||||
if (got_int) {
|
||||
emsg(_(e_interr));
|
||||
}
|
||||
sourcing_name = save_sourcing_name;
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
estack_pop();
|
||||
if (p_verbose > 1) {
|
||||
verbose_enter();
|
||||
smsg(_("finished sourcing %s"), fname);
|
||||
if (sourcing_name != NULL) {
|
||||
smsg(_("continuing in %s"), sourcing_name);
|
||||
if (SOURCING_NAME != NULL) {
|
||||
smsg(_("continuing in %s"), SOURCING_NAME);
|
||||
}
|
||||
verbose_leave();
|
||||
}
|
||||
@ -2110,7 +2193,7 @@ linenr_T get_sourced_lnum(LineGetter fgetline, void *cookie)
|
||||
{
|
||||
return fgetline == getsourceline
|
||||
? ((struct source_cookie *)cookie)->sourcing_lnum
|
||||
: sourcing_lnum;
|
||||
: SOURCING_LNUM;
|
||||
}
|
||||
|
||||
/// Get one full line from a sourced file.
|
||||
@ -2126,14 +2209,14 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat)
|
||||
|
||||
// If breakpoints have been added/deleted need to check for it.
|
||||
if (sp->dbg_tick < debug_tick) {
|
||||
sp->breakpoint = dbg_find_breakpoint(true, (char_u *)sp->fname, sourcing_lnum);
|
||||
sp->breakpoint = dbg_find_breakpoint(true, (char_u *)sp->fname, SOURCING_LNUM);
|
||||
sp->dbg_tick = debug_tick;
|
||||
}
|
||||
if (do_profiling == PROF_YES) {
|
||||
script_line_end();
|
||||
}
|
||||
// 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
|
||||
// one now.
|
||||
if (sp->finished) {
|
||||
@ -2191,10 +2274,10 @@ char *getsourceline(int c, void *cookie, int indent, bool do_concat)
|
||||
}
|
||||
|
||||
// Did we encounter a breakpoint?
|
||||
if (sp->breakpoint != 0 && sp->breakpoint <= sourcing_lnum) {
|
||||
dbg_breakpoint((char_u *)sp->fname, sourcing_lnum);
|
||||
if (sp->breakpoint != 0 && sp->breakpoint <= SOURCING_LNUM) {
|
||||
dbg_breakpoint((char_u *)sp->fname, SOURCING_LNUM);
|
||||
// Find next breakpoint.
|
||||
sp->breakpoint = dbg_find_breakpoint(true, (char_u *)sp->fname, sourcing_lnum);
|
||||
sp->breakpoint = dbg_find_breakpoint(true, (char_u *)sp->fname, SOURCING_LNUM);
|
||||
sp->dbg_tick = debug_tick;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,44 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "nvim/autocmd.h"
|
||||
#include "nvim/eval/typval.h"
|
||||
#include "nvim/ex_cmds_defs.h"
|
||||
#include "nvim/ex_eval_defs.h"
|
||||
|
||||
/// 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 {
|
||||
linenr_T es_lnum; ///< replaces "sourcing_lnum"
|
||||
char *es_name; ///< replaces "sourcing_name"
|
||||
etype_T es_type;
|
||||
union {
|
||||
sctx_T *sctx; ///< script and modeline info
|
||||
ufunc_T *ufunc; ///< function info
|
||||
AutoPatCmd *aucmd; ///< autocommand info
|
||||
except_T *except; ///< exception info
|
||||
} es_info;
|
||||
} estack_T;
|
||||
|
||||
/// Stack of execution contexts. Each entry is an estack_T.
|
||||
/// Current context is at ga_len - 1.
|
||||
extern garray_T exestack;
|
||||
/// 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)
|
||||
|
||||
typedef struct scriptitem_S {
|
||||
char_u *sn_name;
|
||||
|
@ -242,6 +242,7 @@
|
||||
#include "nvim/os/os.h"
|
||||
#include "nvim/path.h"
|
||||
#include "nvim/regexp.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/screen.h"
|
||||
#include "nvim/spell.h"
|
||||
#include "nvim/spell_defs.h"
|
||||
@ -576,8 +577,6 @@ slang_T *spell_load_file(char_u *fname, char_u *lang, slang_T *old_lp, bool sile
|
||||
char_u *p;
|
||||
int n;
|
||||
int len;
|
||||
char_u *save_sourcing_name = (char_u *)sourcing_name;
|
||||
linenr_T save_sourcing_lnum = sourcing_lnum;
|
||||
slang_T *lp = NULL;
|
||||
int c = 0;
|
||||
int res;
|
||||
@ -612,8 +611,7 @@ slang_T *spell_load_file(char_u *fname, char_u *lang, slang_T *old_lp, bool sile
|
||||
}
|
||||
|
||||
// Set sourcing_name, so that error messages mention the file name.
|
||||
sourcing_name = (char *)fname;
|
||||
sourcing_lnum = 0;
|
||||
estack_push(ETYPE_SPELL, (char *)fname, 0);
|
||||
|
||||
// <HEADER>: <fileID>
|
||||
const int scms_ret = spell_check_magic_string(fd);
|
||||
@ -809,8 +807,7 @@ endOK:
|
||||
if (fd != NULL) {
|
||||
fclose(fd);
|
||||
}
|
||||
sourcing_name = (char *)save_sourcing_name;
|
||||
sourcing_lnum = save_sourcing_lnum;
|
||||
estack_pop();
|
||||
|
||||
return lp;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "nvim/eval/encode.h"
|
||||
#include "nvim/ex_docmd.h"
|
||||
#include "nvim/os/os.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/testing.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
@ -17,21 +18,23 @@
|
||||
static void prepare_assert_error(garray_T *gap)
|
||||
{
|
||||
char buf[NUMBUFLEN];
|
||||
char *sname = estack_sfile();
|
||||
|
||||
ga_init(gap, 1, 100);
|
||||
if (sourcing_name != NULL) {
|
||||
ga_concat(gap, (char *)sourcing_name);
|
||||
if (sourcing_lnum > 0) {
|
||||
if (sname != NULL) {
|
||||
ga_concat(gap, sname);
|
||||
if (SOURCING_LNUM > 0) {
|
||||
ga_concat(gap, " ");
|
||||
}
|
||||
}
|
||||
if (sourcing_lnum > 0) {
|
||||
vim_snprintf(buf, ARRAY_SIZE(buf), "line %" PRId64, (int64_t)sourcing_lnum);
|
||||
if (SOURCING_LNUM > 0) {
|
||||
vim_snprintf(buf, ARRAY_SIZE(buf), "line %" PRId64, (int64_t)SOURCING_LNUM);
|
||||
ga_concat(gap, buf);
|
||||
}
|
||||
if (sourcing_name != NULL || sourcing_lnum > 0) {
|
||||
if (sname != NULL || SOURCING_LNUM > 0) {
|
||||
ga_concat(gap, ": ");
|
||||
}
|
||||
xfree(sname);
|
||||
}
|
||||
|
||||
/// Append "p[clen]" to "gap", escaping unprintable characters.
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "nvim/garray.h"
|
||||
#include "nvim/lua/executor.h"
|
||||
#include "nvim/os/input.h"
|
||||
#include "nvim/runtime.h"
|
||||
#include "nvim/usercmd.h"
|
||||
#include "nvim/window.h"
|
||||
|
||||
@ -168,7 +169,7 @@ char *find_ucmd(exarg_T *eap, char *p, int *full, expand_T *xp, int *complp)
|
||||
xp->xp_luaref = uc->uc_compl_luaref;
|
||||
xp->xp_arg = (char *)uc->uc_compl_arg;
|
||||
xp->xp_script_ctx = uc->uc_script_ctx;
|
||||
xp->xp_script_ctx.sc_lnum += sourcing_lnum;
|
||||
xp->xp_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||
}
|
||||
// Do not search for further abbreviations
|
||||
// if this is an exact match.
|
||||
@ -890,7 +891,7 @@ int uc_add_command(char *name, size_t name_len, const char *rep, uint32_t argt,
|
||||
cmd->uc_def = def;
|
||||
cmd->uc_compl = compl;
|
||||
cmd->uc_script_ctx = current_sctx;
|
||||
cmd->uc_script_ctx.sc_lnum += sourcing_lnum;
|
||||
cmd->uc_script_ctx.sc_lnum += SOURCING_LNUM;
|
||||
nlua_set_sctx(&cmd->uc_script_ctx);
|
||||
cmd->uc_compl_arg = (char_u *)compl_arg;
|
||||
cmd->uc_compl_luaref = compl_luaref;
|
||||
|
Loading…
Reference in New Issue
Block a user