aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval/userfunc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval/userfunc.c')
-rw-r--r--src/nvim/eval/userfunc.c129
1 files changed, 70 insertions, 59 deletions
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 2c1cf3eedf..c55a29c67c 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -42,7 +42,7 @@ hashtab_T func_hashtab;
// Used by get_func_tv()
static garray_T funcargs = GA_EMPTY_INIT_VALUE;
-/* pointer to funccal for currently active function */
+// pointer to funccal for currently active function
funccall_T *current_funccal = NULL;
// Pointer to list of previously used funccal, still around because some
@@ -333,7 +333,7 @@ char_u *deref_func_name(const char *name, int *lenp,
///
/// @param ermsg must be passed without translation (use N_() instead of _()).
/// @param name function name
-static void emsg_funcname(char *ermsg, const char_u *name)
+void emsg_funcname(char *ermsg, const char_u *name)
{
char_u *p;
@@ -547,7 +547,7 @@ static void add_nr_var(dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)
static void
free_funccal(
funccall_T *fc,
- int free_val /* a: vars were allocated */
+ int free_val // a: vars were allocated
)
{
for (int i = 0; i < fc->fc_funcs.ga_len; i++) {
@@ -726,7 +726,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
int save_did_emsg;
static int depth = 0;
dictitem_T *v;
- int fixvar_idx = 0; /* index in fixvar[] */
+ int fixvar_idx = 0; // index in fixvar[]
int ai;
bool islambda = false;
char_u numbuf[NUMBUFLEN];
@@ -737,7 +737,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
bool did_save_redo = false;
save_redo_T save_redo;
- /* If depth of calling is getting too high, don't execute the function */
+ // If depth of calling is getting too high, don't execute the function
if (depth >= p_mfd) {
EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'"));
rettv->v_type = VAR_NUMBER;
@@ -764,8 +764,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
fc->linenr = 0;
fc->returned = FALSE;
fc->level = ex_nesting_level;
- /* Check if this function has a breakpoint. */
- fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
+ // Check if this function has a breakpoint.
+ fc->breakpoint = dbg_find_breakpoint(false, fp->uf_name, (linenr_T)0);
fc->dbg_tick = debug_tick;
// Set up fields for closure.
@@ -876,8 +876,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
}
}
- /* Don't redraw while executing the function. */
- ++RedrawingDisabled;
+ // Don't redraw while executing the function.
+ RedrawingDisabled++;
save_sourcing_name = sourcing_name;
save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 1;
@@ -979,7 +979,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
save_did_emsg = did_emsg;
did_emsg = FALSE;
- /* call do_cmdline() to execute the lines */
+ // call do_cmdline() to execute the lines
do_cmdline(NULL, get_func_line, (void *)fc,
DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT);
@@ -1011,7 +1011,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars,
}
}
- /* when being verbose, mention the return value */
+ // when being verbose, mention the return value
if (p_verbose >= 12) {
++no_wait_return;
verbose_enter_scroll();
@@ -1298,6 +1298,10 @@ call_func(
}
if (error == ERROR_NONE && partial->pt_argc > 0) {
for (argv_clear = 0; argv_clear < partial->pt_argc; argv_clear++) {
+ if (argv_clear + argcount_in >= MAX_FUNC_ARGS) {
+ error = ERROR_TOOMANY;
+ goto theend;
+ }
tv_copy(&partial->pt_argv[argv_clear], &argv[argv_clear]);
}
for (int i = 0; i < argcount_in; i++) {
@@ -1311,12 +1315,12 @@ call_func(
if (error == ERROR_NONE && evaluate) {
char_u *rfname = fname;
- /* Ignore "g:" before a function name. */
+ // Ignore "g:" before a function name.
if (fname[0] == 'g' && fname[1] == ':') {
rfname = fname + 2;
}
- rettv->v_type = VAR_NUMBER; /* default rettv is number zero */
+ rettv->v_type = VAR_NUMBER; // default rettv is number zero
rettv->vval.v_number = 0;
error = ERROR_UNKNOWN;
@@ -1338,7 +1342,7 @@ call_func(
if (fp == NULL
&& apply_autocmds(EVENT_FUNCUNDEFINED, rfname, rfname, TRUE, NULL)
&& !aborting()) {
- /* executed an autocommand, search for the function again */
+ // executed an autocommand, search for the function again
fp = find_func(rfname);
}
// Try loading a package.
@@ -1352,7 +1356,9 @@ call_func(
error = ERROR_DELETED;
} else if (fp != NULL) {
if (argv_func != NULL) {
- argcount = argv_func(argcount, argvars, fp->uf_args.ga_len);
+ // postponed filling in the arguments, do it now
+ argcount = argv_func(argcount, argvars, argv_clear,
+ fp->uf_args.ga_len);
}
if (fp->uf_flags & FC_RANGE) {
*doesrange = true;
@@ -1400,10 +1406,9 @@ call_func(
if (error == ERROR_NONE)
ret = OK;
- /*
- * Report an error unless the argument evaluation or function call has been
- * cancelled due to an aborting error, an interrupt, or an exception.
- */
+theend:
+ // Report an error unless the argument evaluation or function call has been
+ // cancelled due to an aborting error, an interrupt, or an exception.
if (!aborting()) {
switch (error) {
case ERROR_UNKNOWN:
@@ -1735,7 +1740,7 @@ void ex_function(exarg_T *eap)
int nesting;
dictitem_T *v;
funcdict_T fudi;
- static int func_nr = 0; /* number for nameless function */
+ static int func_nr = 0; // number for nameless function
int paren;
hashtab_T *ht;
int todo;
@@ -1898,9 +1903,10 @@ void ex_function(exarg_T *eap)
EMSG2(_("E124: Missing '(': %s"), eap->arg);
goto ret_free;
}
- /* attempt to continue by skipping some text */
- if (vim_strchr(p, '(') != NULL)
+ // attempt to continue by skipping some text
+ if (vim_strchr(p, '(') != NULL) {
p = vim_strchr(p, '(');
+ }
}
p = skipwhite(p + 1);
@@ -1922,9 +1928,10 @@ void ex_function(exarg_T *eap)
if (arg[j] != NUL)
emsg_funcname((char *)e_invarg2, arg);
}
- /* Disallow using the g: dict. */
- if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE)
+ // Disallow using the g: dict.
+ if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE) {
EMSG(_("E862: Cannot use g: here"));
+ }
}
if (get_function_args(&p, ')', &newargs, &varargs, eap->skip) == FAIL) {
@@ -2006,7 +2013,7 @@ void ex_function(exarg_T *eap)
need_wait_return = false;
if (line_arg != NULL) {
- /* Use eap->arg, split up in parts by line breaks. */
+ // Use eap->arg, split up in parts by line breaks.
theline = line_arg;
p = vim_strchr(theline, '\n');
if (p == NULL)
@@ -2069,11 +2076,11 @@ void ex_function(exarg_T *eap)
}
}
} else {
- /* skip ':' and blanks*/
- for (p = theline; ascii_iswhite(*p) || *p == ':'; ++p)
- ;
+ // skip ':' and blanks
+ for (p = theline; ascii_iswhite(*p) || *p == ':'; p++) {
+ }
- /* Check for "endfunction". */
+ // Check for "endfunction".
if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) {
if (*p == '!') {
p++;
@@ -2111,7 +2118,7 @@ void ex_function(exarg_T *eap)
|| STRNCMP(p, "try", 3) == 0)
indent += 2;
- /* Check for defining a function inside this function. */
+ // Check for defining a function inside this function.
if (checkforcmd(&p, "function", 2)) {
if (*p == '!') {
p = skipwhite(p + 1);
@@ -2156,9 +2163,8 @@ void ex_function(exarg_T *eap)
|| (p[0] == 'r' && p[1] == 'u' && p[2] == 'b'
&& (!ASCII_ISALPHA(p[3]) || p[3] == 'y'))
|| (p[0] == 'm' && p[1] == 'z'
- && (!ASCII_ISALPHA(p[2]) || p[2] == 's'))
- )) {
- /* ":python <<" continues until a dot, like ":append" */
+ && (!ASCII_ISALPHA(p[2]) || p[2] == 's')))) {
+ // ":python <<" continues until a dot, like ":append"
p = skipwhite(arg + 2);
if (*p == NUL)
skip_until = vim_strsave((char_u *)".");
@@ -2195,7 +2201,7 @@ void ex_function(exarg_T *eap)
}
}
- /* Add the line to the function. */
+ // Add the line to the function.
ga_grow(&newlines, 1 + sourcing_lnum_off);
/* Copy the line to newly allocated memory. get_one_sourceline()
@@ -2209,9 +2215,10 @@ void ex_function(exarg_T *eap)
while (sourcing_lnum_off-- > 0)
((char_u **)(newlines.ga_data))[newlines.ga_len++] = NULL;
- /* Check for end of eap->arg. */
- if (line_arg != NULL && *line_arg == NUL)
+ // Check for end of eap->arg.
+ if (line_arg != NULL && *line_arg == NUL) {
line_arg = NULL;
+ }
}
/* Don't define the function when skipping commands or when an error was
@@ -2292,7 +2299,7 @@ void ex_function(exarg_T *eap)
int slen, plen;
char_u *scriptname;
- /* Check that the autoload name matches the script name. */
+ // Check that the autoload name matches the script name.
int j = FAIL;
if (sourcing_name != NULL) {
scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name));
@@ -2330,11 +2337,11 @@ void ex_function(exarg_T *eap)
fudi.fd_di->di_tv.v_type = VAR_FUNC;
fudi.fd_di->di_tv.vval.v_string = vim_strsave(name);
- /* behave like "dict" was used */
+ // behave like "dict" was used
flags |= FC_DICT;
}
- /* insert the new function in the function list */
+ // insert the new function in the function list
STRCPY(fp->uf_name, name);
if (overwrite) {
hi = hash_find(&func_hashtab, name);
@@ -2688,10 +2695,11 @@ void ex_return(exarg_T *eap)
/* When skipping or the return gets pending, advance to the next command
* in this line (!returning). Otherwise, ignore the rest of the line.
* Following lines will be ignored by get_func_line(). */
- if (returning)
+ if (returning) {
eap->nextcmd = NULL;
- else if (eap->nextcmd == NULL) /* no argument */
+ } else if (eap->nextcmd == NULL) { // no argument
eap->nextcmd = check_nextcmd(arg);
+ }
if (eap->skip)
--emsg_skip;
@@ -2803,7 +2811,8 @@ void ex_call(exarg_T *eap)
}
}
- if (!failed) {
+ // When inside :try we need to check for following "| catch".
+ if (!failed || eap->cstack->cs_trylevel > 0) {
// Check for trailing illegal characters and a following command.
if (!ends_excmd(*arg)) {
emsg_severe = TRUE;
@@ -2831,9 +2840,10 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
int idx;
cstack_T *const cstack = eap->cstack;
- if (reanimate)
- /* Undo the return. */
- current_funccal->returned = FALSE;
+ if (reanimate) {
+ // Undo the return.
+ current_funccal->returned = false;
+ }
/*
* Cleanup (and inactivate) conditionals, but stop when a try conditional
@@ -2859,7 +2869,7 @@ int do_return(exarg_T *eap, int reanimate, int is_cmd, void *rettv)
}
if (rettv != NULL) {
- /* Store the value of the pending return. */
+ // Store the value of the pending return.
cstack->cs_rettv[idx] = xcalloc(1, sizeof(typval_T));
*(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv;
} else
@@ -2925,9 +2935,9 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
funccall_T *fcp = (funccall_T *)cookie;
ufunc_T *fp = fcp->func;
char_u *retval;
- garray_T *gap; /* growarray with function lines */
+ garray_T *gap; // growarray with function lines
- /* If breakpoints have been added/deleted need to check for it. */
+ // 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);
@@ -2938,16 +2948,17 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
gap = &fp->uf_lines;
if (((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
- || fcp->returned)
+ || fcp->returned) {
retval = NULL;
- else {
- /* Skip NULL lines (continuation lines). */
+ } else {
+ // Skip NULL lines (continuation lines).
while (fcp->linenr < gap->ga_len
- && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL)
- ++fcp->linenr;
- if (fcp->linenr >= gap->ga_len)
+ && ((char_u **)(gap->ga_data))[fcp->linenr] == NULL) {
+ fcp->linenr++;
+ }
+ if (fcp->linenr >= gap->ga_len) {
retval = NULL;
- else {
+ } else {
retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]);
sourcing_lnum = fcp->linenr;
if (do_profiling == PROF_YES)
@@ -2955,12 +2966,12 @@ char_u *get_func_line(int c, void *cookie, int indent, bool do_concat)
}
}
- /* Did we encounter a breakpoint? */
+ // Did we encounter a breakpoint?
if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) {
dbg_breakpoint(fp->uf_name, sourcing_lnum);
- /* Find next breakpoint. */
- fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name,
- sourcing_lnum);
+ // Find next breakpoint.
+ fcp->breakpoint = dbg_find_breakpoint(false, fp->uf_name,
+ sourcing_lnum);
fcp->dbg_tick = debug_tick;
}