aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-08-14 05:18:21 +0800
committerGitHub <noreply@github.com>2022-08-14 05:18:21 +0800
commit8cd116729fe2a15d62cd10e5ba7d3dcf1f677337 (patch)
treec3697b80da96e6e1165742979deb121ca491b1d0 /src
parentc1cbe3fb3d2ec1dbcfdc14ee2d9a5e8049d494ae (diff)
parent1ca2247639424994890ef70ab34f2bffa23ddd9f (diff)
downloadrneovim-8cd116729fe2a15d62cd10e5ba7d3dcf1f677337.tar.gz
rneovim-8cd116729fe2a15d62cd10e5ba7d3dcf1f677337.tar.bz2
rneovim-8cd116729fe2a15d62cd10e5ba7d3dcf1f677337.zip
Merge pull request #19752 from zeertzjq/vim-8.2.0056
vim-patch:8.2.{0056,0061,0078,0097,0823}: execution stack
Diffstat (limited to 'src')
-rw-r--r--src/nvim/autocmd.c24
-rw-r--r--src/nvim/autocmd.h21
-rw-r--r--src/nvim/buffer.c15
-rw-r--r--src/nvim/debugger.c36
-rw-r--r--src/nvim/eval.c25
-rw-r--r--src/nvim/eval/funcs.c13
-rw-r--r--src/nvim/eval/typval.h2
-rw-r--r--src/nvim/eval/userfunc.c162
-rw-r--r--src/nvim/ex_docmd.c46
-rw-r--r--src/nvim/ex_eval.c20
-rw-r--r--src/nvim/ex_eval_defs.h6
-rw-r--r--src/nvim/globals.h8
-rw-r--r--src/nvim/highlight_group.c14
-rw-r--r--src/nvim/lua/executor.c6
-rw-r--r--src/nvim/main.c19
-rw-r--r--src/nvim/mapping.c5
-rw-r--r--src/nvim/message.c57
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/profile.c11
-rw-r--r--src/nvim/runtime.c140
-rw-r--r--src/nvim/runtime.h37
-rw-r--r--src/nvim/spellfile.c13
-rw-r--r--src/nvim/testdir/test_autocmd.vim22
-rw-r--r--src/nvim/testdir/test_vimscript.vim17
-rw-r--r--src/nvim/testing.c15
-rw-r--r--src/nvim/usercmd.c5
26 files changed, 463 insertions, 278 deletions
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 4ffd7a4850..0d8efbb830 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -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();
}
diff --git a/src/nvim/autocmd.h b/src/nvim/autocmd.h
index a085a03455..d559d8c3d2 100644
--- a/src/nvim/autocmd.h
+++ b/src/nvim/autocmd.h
@@ -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
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index be376c2109..6262f2d61c 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -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;
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c
index 0eaff06833..76e1caff49 100644
--- a/src/nvim/debugger.c
+++ b/src/nvim/debugger.c
@@ -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);
}
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 0cd2c7314d..ff94cf5944 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -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"
@@ -4187,6 +4188,23 @@ bool garbage_collect(bool testing)
garbage_collect_at_exit = false;
}
+ // The execution stack can grow big, limit the size.
+ if (exestack.ga_maxlen - exestack.ga_len > 500) {
+ // Keep 150% of the current size, with a minimum of the growth size.
+ int n = exestack.ga_len / 2;
+ if (n < exestack.ga_growsize) {
+ n = exestack.ga_growsize;
+ }
+
+ // Don't make it bigger though.
+ if (exestack.ga_len + n < exestack.ga_maxlen) {
+ size_t new_len = (size_t)exestack.ga_itemsize * (size_t)(exestack.ga_len + n);
+ char *pp = xrealloc(exestack.ga_data, new_len);
+ exestack.ga_maxlen = exestack.ga_len + n;
+ exestack.ga_data = pp;
+ }
+ }
+
// We advance by two (COPYID_INC) because we add one for items referenced
// through previous_funccal.
const int copyID = get_copyID();
@@ -8613,8 +8631,7 @@ 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,
+ .es_entry = ((estack_T *)exestack.ga_data)[exestack.ga_len - 1],
.autocmd_fname = autocmd_fname,
.autocmd_match = autocmd_match,
.autocmd_bufnr = autocmd_bufnr,
@@ -8713,8 +8730,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, "?");
}
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index e13046ef82..fe3c0f825e 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -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"
@@ -7317,8 +7318,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
sctx_T save_current_sctx;
- char *save_sourcing_name, *save_autocmd_fname, *save_autocmd_match;
- linenr_T save_sourcing_lnum;
+ char *save_autocmd_fname, *save_autocmd_match;
int save_autocmd_bufnr;
funccal_entry_T funccal_entry;
@@ -7326,16 +7326,14 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
// If this is called from a provider function, restore the scope
// information of the caller.
save_current_sctx = current_sctx;
- save_sourcing_name = sourcing_name;
- save_sourcing_lnum = sourcing_lnum;
save_autocmd_fname = autocmd_fname;
save_autocmd_match = autocmd_match;
save_autocmd_bufnr = autocmd_bufnr;
save_funccal(&funccal_entry);
current_sctx = provider_caller_scope.script_ctx;
- sourcing_name = provider_caller_scope.sourcing_name;
- sourcing_lnum = provider_caller_scope.sourcing_lnum;
+ ga_grow(&exestack, 1);
+ ((estack_T *)exestack.ga_data)[exestack.ga_len++] = provider_caller_scope.es_entry;
autocmd_fname = provider_caller_scope.autocmd_fname;
autocmd_match = provider_caller_scope.autocmd_match;
autocmd_bufnr = provider_caller_scope.autocmd_bufnr;
@@ -7352,8 +7350,7 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, FunPtr fptr)
if (l_provider_call_nesting) {
current_sctx = save_current_sctx;
- sourcing_name = save_sourcing_name;
- sourcing_lnum = save_sourcing_lnum;
+ exestack.ga_len--;
autocmd_fname = save_autocmd_fname;
autocmd_match = save_autocmd_match;
autocmd_bufnr = save_autocmd_bufnr;
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index e411419a07..c4bc9f603b 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -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)
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 3a69e40acb..c527c70be0 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -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);
-
- if (p_verbose >= 12) {
- ++no_wait_return;
- verbose_enter_scroll();
+ estack_push_ufunc(fp, 1);
+ 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;
}
@@ -2458,9 +2442,12 @@ void ex_function(exarg_T *eap)
fp = NULL;
overwrite = true;
} else {
- // redefine existing function
+ char_u *exp_name = fp->uf_name_exp;
+ // redefine existing function, keep the expanded name
XFREE_CLEAR(name);
+ fp->uf_name_exp = NULL;
func_clear_items(fp);
+ fp->uf_name_exp = exp_name;
fp->uf_profiling = false;
fp->uf_prof_initialized = false;
}
@@ -2499,13 +2486,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 +2526,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 +3134,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 +3155,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 +3163,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;
}
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index a681b3c693..5ea6a224d6 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -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