aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/eval.c26
-rw-r--r--src/nvim/eval.h2
-rw-r--r--src/nvim/eval/userfunc.c27
3 files changed, 32 insertions, 23 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index ec3c2b5e85..9660157592 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -2259,21 +2259,23 @@ static int eval_func(char **const arg, evalarg_T *const evalarg, char *const nam
return ret;
}
-/// After using "evalarg" filled from "eap" free the memory.
+/// After using "evalarg" filled from "eap": free the memory.
void clear_evalarg(evalarg_T *evalarg, exarg_T *eap)
{
- if (evalarg != NULL && evalarg->eval_tofree != NULL) {
- if (eap != NULL) {
- // We may need to keep the original command line, e.g. for
- // ":let" it has the variable names. But we may also need the
- // new one, "nextcmd" points into it. Keep both.
- xfree(eap->cmdline_tofree);
- eap->cmdline_tofree = *eap->cmdlinep;
- *eap->cmdlinep = evalarg->eval_tofree;
- } else {
- xfree(evalarg->eval_tofree);
+ if (evalarg != NULL) {
+ if (evalarg->eval_tofree != NULL) {
+ if (eap != NULL) {
+ // We may need to keep the original command line, e.g. for
+ // ":let" it has the variable names. But we may also need the
+ // new one, "nextcmd" points into it. Keep both.
+ xfree(eap->cmdline_tofree);
+ eap->cmdline_tofree = *eap->cmdlinep;
+ *eap->cmdlinep = evalarg->eval_tofree;
+ } else {
+ xfree(evalarg->eval_tofree);
+ }
+ evalarg->eval_tofree = NULL;
}
- evalarg->eval_tofree = NULL;
}
}
diff --git a/src/nvim/eval.h b/src/nvim/eval.h
index 4e0eb6ebb8..e9cdb108a8 100644
--- a/src/nvim/eval.h
+++ b/src/nvim/eval.h
@@ -275,7 +275,7 @@ typedef struct {
LineGetter eval_getline;
void *eval_cookie; ///< argument for eval_getline()
- /// pointer to the line obtained with getsourceline()
+ /// pointer to the last line obtained with getsourceline()
char *eval_tofree;
} evalarg_T;
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 3fc34471bf..9440ceb36e 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -261,15 +261,14 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
partial_T *pt = NULL;
int varargs;
int ret;
- char *start = skipwhite(*arg + 1);
- char *s, *e;
bool *old_eval_lavars = eval_lavars_used;
bool eval_lavars = false;
char *tofree = NULL;
// First, check if this is a lambda expression. "->" must exists.
- ret = get_function_args(&start, '-', NULL, NULL, NULL, true);
- if (ret == FAIL || *start != '>') {
+ char *s = skipwhite(*arg + 1);
+ ret = get_function_args(&s, '-', NULL, NULL, NULL, true);
+ if (ret == FAIL || *s != '>') {
return NOTDONE;
}
@@ -292,8 +291,9 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
// Get the start and the end of the expression.
*arg = skipwhite((*arg) + 1);
- s = *arg;
+ char *start = *arg;
ret = skip_expr(arg, evalarg);
+ char *end = *arg;
if (ret == FAIL) {
goto errret;
}
@@ -303,7 +303,6 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
evalarg->eval_tofree = NULL;
}
- e = *arg;
*arg = skipwhite(*arg);
if (**arg != '}') {
semsg(_("E451: Expected }: %s"), *arg);
@@ -325,11 +324,11 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
ga_grow(&newlines, 1);
// Add "return " before the expression.
- size_t len = (size_t)(7 + e - s + 1);
+ size_t len = (size_t)(7 + end - start + 1);
p = xmalloc(len);
((char **)(newlines.ga_data))[newlines.ga_len++] = p;
STRCPY(p, "return ");
- xstrlcpy(p + 7, s, (size_t)(e - s) + 1);
+ xstrlcpy(p + 7, start, (size_t)(end - start) + 1);
if (strstr(p + 7, "a:") == NULL) {
// No a: variables are used for sure.
flags |= FC_NOARGS;
@@ -367,14 +366,22 @@ int get_lambda_tv(char **arg, typval_T *rettv, evalarg_T *evalarg)
}
eval_lavars_used = old_eval_lavars;
- xfree(tofree);
+ if (evalarg->eval_tofree == NULL) {
+ evalarg->eval_tofree = tofree;
+ } else {
+ xfree(tofree);
+ }
return OK;
errret:
ga_clear_strings(&newargs);
xfree(fp);
xfree(pt);
- xfree(tofree);
+ if (evalarg->eval_tofree == NULL) {
+ evalarg->eval_tofree = tofree;
+ } else {
+ xfree(tofree);
+ }
eval_lavars_used = old_eval_lavars;
return FAIL;
}