patch 9.0.0634: evaluating "expr" options has more overhead than needed
Problem: Evaluating "expr" options has more overhead than needed.
Solution: Use call_simple_func() for 'foldtext', 'includeexpr', 'printexpr',
"expr" of 'spellsuggest', 'diffexpr', 'patchexpr', 'balloonexpr',
'formatexpr', 'indentexpr' and 'charconvert'.
This commit is contained in:
@ -376,6 +376,9 @@ Additionally, 'diffexpr' should take care of "icase" and "iwhite" in the
|
|||||||
'diffopt' option. 'diffexpr' cannot change the value of 'lines' and
|
'diffopt' option. 'diffexpr' cannot change the value of 'lines' and
|
||||||
'columns'.
|
'columns'.
|
||||||
|
|
||||||
|
The advantage of using a function call without arguments is that it is faster,
|
||||||
|
see |expr-option-function|.
|
||||||
|
|
||||||
Example (this does almost the same as 'diffexpr' being empty): >
|
Example (this does almost the same as 'diffexpr' being empty): >
|
||||||
|
|
||||||
set diffexpr=MyDiff()
|
set diffexpr=MyDiff()
|
||||||
@ -441,6 +444,9 @@ will have the same effect. These variables are set to the file names used:
|
|||||||
v:fname_diff patch file
|
v:fname_diff patch file
|
||||||
v:fname_out resulting patched file
|
v:fname_out resulting patched file
|
||||||
|
|
||||||
|
The advantage of using a function call without arguments is that it is faster,
|
||||||
|
see |expr-option-function|.
|
||||||
|
|
||||||
Example (this does the same as 'patchexpr' being empty): >
|
Example (this does the same as 'patchexpr' being empty): >
|
||||||
|
|
||||||
set patchexpr=MyPatch()
|
set patchexpr=MyPatch()
|
||||||
|
|||||||
@ -1626,6 +1626,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
Note that v:charconvert_from and v:charconvert_to may be different
|
Note that v:charconvert_from and v:charconvert_to may be different
|
||||||
from 'encoding'. Vim internally uses UTF-8 instead of UCS-2 or UCS-4.
|
from 'encoding'. Vim internally uses UTF-8 instead of UCS-2 or UCS-4.
|
||||||
|
|
||||||
|
The advantage of using a function call without arguments is that it is
|
||||||
|
faster, see |expr-option-function|.
|
||||||
|
|
||||||
Encryption is not done by Vim when using 'charconvert'. If you want
|
Encryption is not done by Vim when using 'charconvert'. If you want
|
||||||
to encrypt the file after conversion, 'charconvert' should take care
|
to encrypt the file after conversion, 'charconvert' should take care
|
||||||
of this.
|
of this.
|
||||||
@ -3664,6 +3667,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
< This will invoke the mylang#Format() function in the
|
< This will invoke the mylang#Format() function in the
|
||||||
autoload/mylang.vim file in 'runtimepath'. |autoload|
|
autoload/mylang.vim file in 'runtimepath'. |autoload|
|
||||||
|
|
||||||
|
The advantage of using a function call without arguments is that it is
|
||||||
|
faster, see |expr-option-function|.
|
||||||
|
|
||||||
The expression is also evaluated when 'textwidth' is set and adding
|
The expression is also evaluated when 'textwidth' is set and adding
|
||||||
text beyond that limit. This happens under the same conditions as
|
text beyond that limit. This happens under the same conditions as
|
||||||
when internal formatting is used. Make sure the cursor is kept in the
|
when internal formatting is used. Make sure the cursor is kept in the
|
||||||
@ -4534,11 +4540,14 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
|
|
||||||
If the expression starts with s: or |<SID>|, then it is replaced with
|
If the expression starts with s: or |<SID>|, then it is replaced with
|
||||||
the script ID (|local-function|). Example: >
|
the script ID (|local-function|). Example: >
|
||||||
set includeexpr=s:MyIncludeExpr(v:fname)
|
set includeexpr=s:MyIncludeExpr()
|
||||||
set includeexpr=<SID>SomeIncludeExpr(v:fname)
|
set includeexpr=<SID>SomeIncludeExpr()
|
||||||
< Otherwise, the expression is evaluated in the context of the script
|
< Otherwise, the expression is evaluated in the context of the script
|
||||||
where the option was set, thus script-local items are available.
|
where the option was set, thus script-local items are available.
|
||||||
|
|
||||||
|
It is more efficient if the value is just a function call without
|
||||||
|
arguments, see |expr-option-function|.
|
||||||
|
|
||||||
The expression will be evaluated in the |sandbox| when set from a
|
The expression will be evaluated in the |sandbox| when set from a
|
||||||
modeline, see |sandbox-option|.
|
modeline, see |sandbox-option|.
|
||||||
This option cannot be set in a modeline when 'modelineexpr' is off.
|
This option cannot be set in a modeline when 'modelineexpr' is off.
|
||||||
@ -4620,6 +4629,9 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
< Otherwise, the expression is evaluated in the context of the script
|
< Otherwise, the expression is evaluated in the context of the script
|
||||||
where the option was set, thus script-local items are available.
|
where the option was set, thus script-local items are available.
|
||||||
|
|
||||||
|
The advantage of using a function call without arguments is that it is
|
||||||
|
faster, see |expr-option-function|.
|
||||||
|
|
||||||
The expression must return the number of spaces worth of indent. It
|
The expression must return the number of spaces worth of indent. It
|
||||||
can return "-1" to keep the current indent (this means 'autoindent' is
|
can return "-1" to keep the current indent (this means 'autoindent' is
|
||||||
used for the indent).
|
used for the indent).
|
||||||
@ -7470,9 +7482,11 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
The file is used for all languages.
|
The file is used for all languages.
|
||||||
|
|
||||||
expr:{expr} Evaluate expression {expr}. Use a function to avoid
|
expr:{expr} Evaluate expression {expr}. Use a function to avoid
|
||||||
trouble with spaces. |v:val| holds the badly spelled
|
trouble with spaces. Best is to call a function
|
||||||
word. The expression must evaluate to a List of
|
without arguments, see |expr-option-function|.
|
||||||
Lists, each with a suggestion and a score.
|
|v:val| holds the badly spelled word. The expression
|
||||||
|
must evaluate to a List of Lists, each with a
|
||||||
|
suggestion and a score.
|
||||||
Example:
|
Example:
|
||||||
[['the', 33], ['that', 44]] ~
|
[['the', 33], ['that', 44]] ~
|
||||||
Set 'verbose' and use |z=| to see the scores that the
|
Set 'verbose' and use |z=| to see the scores that the
|
||||||
|
|||||||
@ -158,13 +158,16 @@ currently specified printdevice: >
|
|||||||
If you change this option, using a function is an easy way to avoid having to
|
If you change this option, using a function is an easy way to avoid having to
|
||||||
escape all the spaces. Example: >
|
escape all the spaces. Example: >
|
||||||
|
|
||||||
:set printexpr=PrintFile(v:fname_in)
|
:set printexpr=PrintFile()
|
||||||
:function PrintFile(fname)
|
:function PrintFile()
|
||||||
: call system("ghostview " .. a:fname)
|
: call system("ghostview " .. v:fname_in)
|
||||||
: call delete(a:fname)
|
: call delete(v:fname_in)
|
||||||
: return v:shell_error
|
: return v:shell_error
|
||||||
:endfunc
|
:endfunc
|
||||||
|
|
||||||
|
It is more efficient if the option is set to just a function call,
|
||||||
|
see |expr-option-function|.
|
||||||
|
|
||||||
Be aware that some print programs return control before they have read the
|
Be aware that some print programs return control before they have read the
|
||||||
file. If you delete the file too soon it will not be printed. These programs
|
file. If you delete the file too soon it will not be printed. These programs
|
||||||
usually offer an option to have them remove the file when printing is done.
|
usually offer an option to have them remove the file when printing is done.
|
||||||
|
|||||||
@ -278,7 +278,7 @@ bexpr_eval(
|
|||||||
current_sctx = curbuf->b_p_script_ctx[BV_BEXPR];
|
current_sctx = curbuf->b_p_script_ctx[BV_BEXPR];
|
||||||
|
|
||||||
vim_free(result);
|
vim_free(result);
|
||||||
result = eval_to_string(bexpr, TRUE);
|
result = eval_to_string(bexpr, TRUE, TRUE);
|
||||||
|
|
||||||
// Remove one trailing newline, it is added when the result was a
|
// Remove one trailing newline, it is added when the result was a
|
||||||
// list and it's hardly ever useful. If the user really wants a
|
// list and it's hardly ever useful. If the user really wants a
|
||||||
|
|||||||
@ -4246,7 +4246,7 @@ build_stl_str_hl(
|
|||||||
tv.vval.v_number = wp->w_id;
|
tv.vval.v_number = wp->w_id;
|
||||||
set_var((char_u *)"g:statusline_winid", &tv, FALSE);
|
set_var((char_u *)"g:statusline_winid", &tv, FALSE);
|
||||||
|
|
||||||
usefmt = eval_to_string_safe(fmt + 2, use_sandbox, FALSE);
|
usefmt = eval_to_string_safe(fmt + 2, use_sandbox, FALSE, FALSE);
|
||||||
if (usefmt == NULL)
|
if (usefmt == NULL)
|
||||||
usefmt = fmt;
|
usefmt = fmt;
|
||||||
|
|
||||||
@ -4633,7 +4633,7 @@ build_stl_str_hl(
|
|||||||
if (curwin != save_curwin)
|
if (curwin != save_curwin)
|
||||||
VIsual_active = FALSE;
|
VIsual_active = FALSE;
|
||||||
|
|
||||||
str = eval_to_string_safe(p, use_sandbox, FALSE);
|
str = eval_to_string_safe(p, use_sandbox, FALSE, FALSE);
|
||||||
|
|
||||||
curwin = save_curwin;
|
curwin = save_curwin;
|
||||||
curbuf = save_curbuf;
|
curbuf = save_curbuf;
|
||||||
|
|||||||
@ -86,7 +86,7 @@ eval_client_expr_to_string(char_u *expr)
|
|||||||
// to be typed. Do generate errors so that try/catch works.
|
// to be typed. Do generate errors so that try/catch works.
|
||||||
++emsg_silent;
|
++emsg_silent;
|
||||||
|
|
||||||
res = eval_to_string(expr, TRUE);
|
res = eval_to_string(expr, TRUE, FALSE);
|
||||||
|
|
||||||
debug_break_level = save_dbl;
|
debug_break_level = save_dbl;
|
||||||
redir_off = save_ro;
|
redir_off = save_ro;
|
||||||
|
|||||||
129
src/eval.c
129
src/eval.c
@ -143,17 +143,23 @@ eval_to_bool(
|
|||||||
char_u *arg,
|
char_u *arg,
|
||||||
int *error,
|
int *error,
|
||||||
exarg_T *eap,
|
exarg_T *eap,
|
||||||
int skip) // only parse, don't execute
|
int skip, // only parse, don't execute
|
||||||
|
int use_simple_function)
|
||||||
{
|
{
|
||||||
typval_T tv;
|
typval_T tv;
|
||||||
varnumber_T retval = FALSE;
|
varnumber_T retval = FALSE;
|
||||||
evalarg_T evalarg;
|
evalarg_T evalarg;
|
||||||
|
int r;
|
||||||
|
|
||||||
fill_evalarg_from_eap(&evalarg, eap, skip);
|
fill_evalarg_from_eap(&evalarg, eap, skip);
|
||||||
|
|
||||||
if (skip)
|
if (skip)
|
||||||
++emsg_skip;
|
++emsg_skip;
|
||||||
if (eval0(arg, &tv, eap, &evalarg) == FAIL)
|
if (use_simple_function)
|
||||||
|
r = eval0_simple_funccal(arg, &tv, eap, &evalarg);
|
||||||
|
else
|
||||||
|
r = eval0(arg, &tv, eap, &evalarg);
|
||||||
|
if (r == FAIL)
|
||||||
*error = TRUE;
|
*error = TRUE;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -601,14 +607,20 @@ typval2string(typval_T *tv, int convert)
|
|||||||
eval_to_string_eap(
|
eval_to_string_eap(
|
||||||
char_u *arg,
|
char_u *arg,
|
||||||
int convert,
|
int convert,
|
||||||
exarg_T *eap)
|
exarg_T *eap,
|
||||||
|
int use_simple_function)
|
||||||
{
|
{
|
||||||
typval_T tv;
|
typval_T tv;
|
||||||
char_u *retval;
|
char_u *retval;
|
||||||
evalarg_T evalarg;
|
evalarg_T evalarg;
|
||||||
|
int r;
|
||||||
|
|
||||||
fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip);
|
fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip);
|
||||||
if (eval0(arg, &tv, NULL, &evalarg) == FAIL)
|
if (use_simple_function)
|
||||||
|
r = eval0_simple_funccal(arg, &tv, NULL, &evalarg);
|
||||||
|
else
|
||||||
|
r = eval0(arg, &tv, NULL, &evalarg);
|
||||||
|
if (r == FAIL)
|
||||||
retval = NULL;
|
retval = NULL;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -623,9 +635,10 @@ eval_to_string_eap(
|
|||||||
char_u *
|
char_u *
|
||||||
eval_to_string(
|
eval_to_string(
|
||||||
char_u *arg,
|
char_u *arg,
|
||||||
int convert)
|
int convert,
|
||||||
|
int use_simple_function)
|
||||||
{
|
{
|
||||||
return eval_to_string_eap(arg, convert, NULL);
|
return eval_to_string_eap(arg, convert, NULL, use_simple_function);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -637,7 +650,8 @@ eval_to_string(
|
|||||||
eval_to_string_safe(
|
eval_to_string_safe(
|
||||||
char_u *arg,
|
char_u *arg,
|
||||||
int use_sandbox,
|
int use_sandbox,
|
||||||
int keep_script_version)
|
int keep_script_version,
|
||||||
|
int use_simple_function)
|
||||||
{
|
{
|
||||||
char_u *retval;
|
char_u *retval;
|
||||||
funccal_entry_T funccal_entry;
|
funccal_entry_T funccal_entry;
|
||||||
@ -651,7 +665,7 @@ eval_to_string_safe(
|
|||||||
++sandbox;
|
++sandbox;
|
||||||
++textlock;
|
++textlock;
|
||||||
may_garbage_collect = FALSE;
|
may_garbage_collect = FALSE;
|
||||||
retval = eval_to_string(arg, FALSE);
|
retval = eval_to_string(arg, FALSE, use_simple_function);
|
||||||
if (use_sandbox)
|
if (use_sandbox)
|
||||||
--sandbox;
|
--sandbox;
|
||||||
--textlock;
|
--textlock;
|
||||||
@ -667,15 +681,20 @@ eval_to_string_safe(
|
|||||||
* Returns -1 for an error.
|
* Returns -1 for an error.
|
||||||
*/
|
*/
|
||||||
varnumber_T
|
varnumber_T
|
||||||
eval_to_number(char_u *expr)
|
eval_to_number(char_u *expr, int use_simple_function)
|
||||||
{
|
{
|
||||||
typval_T rettv;
|
typval_T rettv;
|
||||||
varnumber_T retval;
|
varnumber_T retval;
|
||||||
char_u *p = skipwhite(expr);
|
char_u *p = skipwhite(expr);
|
||||||
|
int r = NOTDONE;
|
||||||
|
|
||||||
++emsg_off;
|
++emsg_off;
|
||||||
|
|
||||||
if (eval1(&p, &rettv, &EVALARG_EVALUATE) == FAIL)
|
if (use_simple_function)
|
||||||
|
r = may_call_simple_func(expr, &rettv);
|
||||||
|
if (r == NOTDONE)
|
||||||
|
r = eval1(&p, &rettv, &EVALARG_EVALUATE);
|
||||||
|
if (r == FAIL)
|
||||||
retval = -1;
|
retval = -1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -694,6 +713,12 @@ eval_to_number(char_u *expr)
|
|||||||
*/
|
*/
|
||||||
typval_T *
|
typval_T *
|
||||||
eval_expr(char_u *arg, exarg_T *eap)
|
eval_expr(char_u *arg, exarg_T *eap)
|
||||||
|
{
|
||||||
|
return eval_expr_ext(arg, eap, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
typval_T *
|
||||||
|
eval_expr_ext(char_u *arg, exarg_T *eap, int use_simple_function)
|
||||||
{
|
{
|
||||||
typval_T *tv;
|
typval_T *tv;
|
||||||
evalarg_T evalarg;
|
evalarg_T evalarg;
|
||||||
@ -701,8 +726,18 @@ eval_expr(char_u *arg, exarg_T *eap)
|
|||||||
fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip);
|
fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip);
|
||||||
|
|
||||||
tv = ALLOC_ONE(typval_T);
|
tv = ALLOC_ONE(typval_T);
|
||||||
if (tv != NULL && eval0(arg, tv, eap, &evalarg) == FAIL)
|
if (tv != NULL)
|
||||||
VIM_CLEAR(tv);
|
{
|
||||||
|
int r = NOTDONE;
|
||||||
|
|
||||||
|
if (use_simple_function)
|
||||||
|
r = eval0_simple_funccal(arg, tv, eap, &evalarg);
|
||||||
|
if (r == NOTDONE)
|
||||||
|
r = eval0(arg, tv, eap, &evalarg);
|
||||||
|
|
||||||
|
if (r == FAIL)
|
||||||
|
VIM_CLEAR(tv);
|
||||||
|
}
|
||||||
|
|
||||||
clear_evalarg(&evalarg, eap);
|
clear_evalarg(&evalarg, eap);
|
||||||
return tv;
|
return tv;
|
||||||
@ -899,12 +934,11 @@ eval_foldexpr(win_T *wp, int *cp)
|
|||||||
{
|
{
|
||||||
char_u *arg;
|
char_u *arg;
|
||||||
typval_T tv;
|
typval_T tv;
|
||||||
int r = NOTDONE;
|
|
||||||
varnumber_T retval;
|
varnumber_T retval;
|
||||||
char_u *s;
|
char_u *s;
|
||||||
sctx_T saved_sctx = current_sctx;
|
sctx_T saved_sctx = current_sctx;
|
||||||
int use_sandbox = was_set_insecurely((char_u *)"foldexpr",
|
int use_sandbox = was_set_insecurely((char_u *)"foldexpr",
|
||||||
OPT_LOCAL);
|
OPT_LOCAL);
|
||||||
|
|
||||||
arg = skipwhite(wp->w_p_fde);
|
arg = skipwhite(wp->w_p_fde);
|
||||||
current_sctx = wp->w_p_script_ctx[WV_FDE];
|
current_sctx = wp->w_p_script_ctx[WV_FDE];
|
||||||
@ -915,20 +949,9 @@ eval_foldexpr(win_T *wp, int *cp)
|
|||||||
++textlock;
|
++textlock;
|
||||||
*cp = NUL;
|
*cp = NUL;
|
||||||
|
|
||||||
// If the expression is "FuncName()" then we can skip a lot of overhead.
|
// Evaluate the expression. If the expression is "FuncName()" call the
|
||||||
char_u *parens = (char_u *)strstr((char *)arg, "()");
|
// function directly.
|
||||||
if (parens != NULL && *skipwhite(parens + 2) == NUL)
|
if (eval0_simple_funccal(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL)
|
||||||
{
|
|
||||||
char_u *p = STRNCMP(arg, "<SNR>", 5) == 0 ? skipdigits(arg + 5) : arg;
|
|
||||||
|
|
||||||
if (to_name_end(p, TRUE) == parens)
|
|
||||||
r = call_simple_func(arg, (int)(parens - arg), &tv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r == NOTDONE)
|
|
||||||
r = eval0(arg, &tv, NULL, &EVALARG_EVALUATE);
|
|
||||||
|
|
||||||
if (r == FAIL)
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2428,9 +2451,10 @@ skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The "evaluate" argument: When FALSE, the argument is only parsed but not
|
* The "eval" functions have an "evalarg" argument: When NULL or
|
||||||
* executed. The function may return OK, but the rettv will be of type
|
* "evalarg->eval_flags" does not have EVAL_EVALUATE, then the argument is only
|
||||||
* VAR_UNKNOWN. The function still returns FAIL for a syntax error.
|
* parsed but not executed. The functions may return OK, but the rettv will be
|
||||||
|
* of type VAR_UNKNOWN. The functions still returns FAIL for a syntax error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2451,6 +2475,47 @@ eval0(
|
|||||||
return eval0_retarg(arg, rettv, eap, evalarg, NULL);
|
return eval0_retarg(arg, rettv, eap, evalarg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If "arg" is a simple function call without arguments then call it and return
|
||||||
|
* the result. Otherwise return NOTDONE.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
may_call_simple_func(
|
||||||
|
char_u *arg,
|
||||||
|
typval_T *rettv)
|
||||||
|
{
|
||||||
|
char_u *parens = (char_u *)strstr((char *)arg, "()");
|
||||||
|
int r = NOTDONE;
|
||||||
|
|
||||||
|
// If the expression is "FuncName()" then we can skip a lot of overhead.
|
||||||
|
if (parens != NULL && *skipwhite(parens + 2) == NUL)
|
||||||
|
{
|
||||||
|
char_u *p = STRNCMP(arg, "<SNR>", 5) == 0 ? skipdigits(arg + 5) : arg;
|
||||||
|
|
||||||
|
if (to_name_end(p, TRUE) == parens)
|
||||||
|
r = call_simple_func(arg, (int)(parens - arg), rettv);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle zero level expression with optimization for a simple function call.
|
||||||
|
* Same arguments and return value as eval0().
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
eval0_simple_funccal(
|
||||||
|
char_u *arg,
|
||||||
|
typval_T *rettv,
|
||||||
|
exarg_T *eap,
|
||||||
|
evalarg_T *evalarg)
|
||||||
|
{
|
||||||
|
int r = may_call_simple_func(arg, rettv);
|
||||||
|
|
||||||
|
if (r == NOTDONE)
|
||||||
|
r = eval0_retarg(arg, rettv, eap, evalarg, NULL);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Like eval0() but when "retarg" is not NULL store the pointer to after the
|
* Like eval0() but when "retarg" is not NULL store the pointer to after the
|
||||||
* expression and don't check what comes after the expression.
|
* expression and don't check what comes after the expression.
|
||||||
@ -6283,7 +6348,7 @@ make_expanded_name(
|
|||||||
c1 = *in_end;
|
c1 = *in_end;
|
||||||
*in_end = NUL;
|
*in_end = NUL;
|
||||||
|
|
||||||
temp_result = eval_to_string(expr_start + 1, FALSE);
|
temp_result = eval_to_string(expr_start + 1, FALSE, FALSE);
|
||||||
if (temp_result != NULL)
|
if (temp_result != NULL)
|
||||||
{
|
{
|
||||||
retval = alloc(STRLEN(temp_result) + (expr_start - in_start)
|
retval = alloc(STRLEN(temp_result) + (expr_start - in_start)
|
||||||
|
|||||||
@ -380,7 +380,7 @@ eval_charconvert(
|
|||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
current_sctx = *ctx;
|
current_sctx = *ctx;
|
||||||
|
|
||||||
if (eval_to_bool(p_ccv, &err, NULL, FALSE))
|
if (eval_to_bool(p_ccv, &err, NULL, FALSE, TRUE))
|
||||||
err = TRUE;
|
err = TRUE;
|
||||||
|
|
||||||
set_vim_var_string(VV_CC_FROM, NULL, -1);
|
set_vim_var_string(VV_CC_FROM, NULL, -1);
|
||||||
@ -408,7 +408,7 @@ eval_printexpr(char_u *fname, char_u *args)
|
|||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
current_sctx = *ctx;
|
current_sctx = *ctx;
|
||||||
|
|
||||||
if (eval_to_bool(p_pexpr, &err, NULL, FALSE))
|
if (eval_to_bool(p_pexpr, &err, NULL, FALSE, TRUE))
|
||||||
err = TRUE;
|
err = TRUE;
|
||||||
|
|
||||||
set_vim_var_string(VV_FNAME_IN, NULL, -1);
|
set_vim_var_string(VV_FNAME_IN, NULL, -1);
|
||||||
@ -444,7 +444,7 @@ eval_diff(
|
|||||||
current_sctx = *ctx;
|
current_sctx = *ctx;
|
||||||
|
|
||||||
// errors are ignored
|
// errors are ignored
|
||||||
tv = eval_expr(p_dex, NULL);
|
tv = eval_expr_ext(p_dex, NULL, TRUE);
|
||||||
free_tv(tv);
|
free_tv(tv);
|
||||||
|
|
||||||
set_vim_var_string(VV_FNAME_IN, NULL, -1);
|
set_vim_var_string(VV_FNAME_IN, NULL, -1);
|
||||||
@ -472,7 +472,7 @@ eval_patch(
|
|||||||
current_sctx = *ctx;
|
current_sctx = *ctx;
|
||||||
|
|
||||||
// errors are ignored
|
// errors are ignored
|
||||||
tv = eval_expr(p_pex, NULL);
|
tv = eval_expr_ext(p_pex, NULL, TRUE);
|
||||||
free_tv(tv);
|
free_tv(tv);
|
||||||
|
|
||||||
set_vim_var_string(VV_FNAME_IN, NULL, -1);
|
set_vim_var_string(VV_FNAME_IN, NULL, -1);
|
||||||
@ -497,6 +497,7 @@ eval_spell_expr(char_u *badword, char_u *expr)
|
|||||||
char_u *p = skipwhite(expr);
|
char_u *p = skipwhite(expr);
|
||||||
sctx_T saved_sctx = current_sctx;
|
sctx_T saved_sctx = current_sctx;
|
||||||
sctx_T *ctx;
|
sctx_T *ctx;
|
||||||
|
int r;
|
||||||
|
|
||||||
// Set "v:val" to the bad word.
|
// Set "v:val" to the bad word.
|
||||||
prepare_vimvar(VV_VAL, &save_val);
|
prepare_vimvar(VV_VAL, &save_val);
|
||||||
@ -507,7 +508,10 @@ eval_spell_expr(char_u *badword, char_u *expr)
|
|||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
current_sctx = *ctx;
|
current_sctx = *ctx;
|
||||||
|
|
||||||
if (eval1(&p, &rettv, &EVALARG_EVALUATE) == OK)
|
r = may_call_simple_func(p, &rettv);
|
||||||
|
if (r == NOTDONE)
|
||||||
|
r = eval1(&p, &rettv, &EVALARG_EVALUATE);
|
||||||
|
if (r == OK)
|
||||||
{
|
{
|
||||||
if (rettv.v_type != VAR_LIST)
|
if (rettv.v_type != VAR_LIST)
|
||||||
clear_tv(&rettv);
|
clear_tv(&rettv);
|
||||||
@ -643,7 +647,7 @@ eval_one_expr_in_str(char_u *p, garray_T *gap, int evaluate)
|
|||||||
if (evaluate)
|
if (evaluate)
|
||||||
{
|
{
|
||||||
*block_end = NUL;
|
*block_end = NUL;
|
||||||
expr_val = eval_to_string(block_start, TRUE);
|
expr_val = eval_to_string(block_start, TRUE, FALSE);
|
||||||
*block_end = '}';
|
*block_end = '}';
|
||||||
if (expr_val == NULL)
|
if (expr_val == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@ -5778,7 +5778,7 @@ ex_colorscheme(exarg_T *eap)
|
|||||||
if (expr != NULL)
|
if (expr != NULL)
|
||||||
{
|
{
|
||||||
++emsg_off;
|
++emsg_off;
|
||||||
p = eval_to_string(expr, FALSE);
|
p = eval_to_string(expr, FALSE, FALSE);
|
||||||
--emsg_off;
|
--emsg_off;
|
||||||
vim_free(expr);
|
vim_free(expr);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1047,7 +1047,7 @@ ex_if(exarg_T *eap)
|
|||||||
skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
|
skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
|
||||||
&& !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
|
&& !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
|
||||||
|
|
||||||
result = eval_to_bool(eap->arg, &error, eap, skip);
|
result = eval_to_bool(eap->arg, &error, eap, skip, FALSE);
|
||||||
|
|
||||||
if (!skip && !error)
|
if (!skip && !error)
|
||||||
{
|
{
|
||||||
@ -1176,7 +1176,7 @@ ex_else(exarg_T *eap)
|
|||||||
if (skip && ends_excmd(*eap->arg))
|
if (skip && ends_excmd(*eap->arg))
|
||||||
semsg(_(e_invalid_expression_str), eap->arg);
|
semsg(_(e_invalid_expression_str), eap->arg);
|
||||||
else
|
else
|
||||||
result = eval_to_bool(eap->arg, &error, eap, skip);
|
result = eval_to_bool(eap->arg, &error, eap, skip, FALSE);
|
||||||
|
|
||||||
// When throwing error exceptions, we want to throw always the first
|
// When throwing error exceptions, we want to throw always the first
|
||||||
// of several errors in a row. This is what actually happens when
|
// of several errors in a row. This is what actually happens when
|
||||||
@ -1283,7 +1283,7 @@ ex_while(exarg_T *eap)
|
|||||||
/*
|
/*
|
||||||
* ":while bool-expr"
|
* ":while bool-expr"
|
||||||
*/
|
*/
|
||||||
result = eval_to_bool(eap->arg, &error, eap, skip);
|
result = eval_to_bool(eap->arg, &error, eap, skip, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -3354,7 +3354,7 @@ expand_backtick(
|
|||||||
|
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
if (*cmd == '=') // `={expr}`: Expand expression
|
if (*cmd == '=') // `={expr}`: Expand expression
|
||||||
buffer = eval_to_string(cmd + 1, TRUE);
|
buffer = eval_to_string(cmd + 1, TRUE, FALSE);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
buffer = get_cmd_output(cmd, NULL,
|
buffer = get_cmd_output(cmd, NULL,
|
||||||
|
|||||||
@ -2002,7 +2002,8 @@ eval_includeexpr(char_u *ptr, int len)
|
|||||||
current_sctx = curbuf->b_p_script_ctx[BV_INEX];
|
current_sctx = curbuf->b_p_script_ctx[BV_INEX];
|
||||||
|
|
||||||
res = eval_to_string_safe(curbuf->b_p_inex,
|
res = eval_to_string_safe(curbuf->b_p_inex,
|
||||||
was_set_insecurely((char_u *)"includeexpr", OPT_LOCAL), TRUE);
|
was_set_insecurely((char_u *)"includeexpr", OPT_LOCAL),
|
||||||
|
TRUE, TRUE);
|
||||||
|
|
||||||
set_vim_var_string(VV_FNAME, NULL, 0);
|
set_vim_var_string(VV_FNAME, NULL, 0);
|
||||||
current_sctx = save_sctx;
|
current_sctx = save_sctx;
|
||||||
|
|||||||
@ -1960,7 +1960,8 @@ get_foldtext(
|
|||||||
|
|
||||||
++emsg_off; // handle exceptions, but don't display errors
|
++emsg_off; // handle exceptions, but don't display errors
|
||||||
text = eval_to_string_safe(wp->w_p_fdt,
|
text = eval_to_string_safe(wp->w_p_fdt,
|
||||||
was_set_insecurely((char_u *)"foldtext", OPT_LOCAL), TRUE);
|
was_set_insecurely((char_u *)"foldtext", OPT_LOCAL),
|
||||||
|
TRUE, TRUE);
|
||||||
--emsg_off;
|
--emsg_off;
|
||||||
|
|
||||||
if (text == NULL || did_emsg)
|
if (text == NULL || did_emsg)
|
||||||
|
|||||||
@ -381,7 +381,7 @@ CVim::Eval(BSTR expr, BSTR *result)
|
|||||||
|
|
||||||
/* Evaluate the expression */
|
/* Evaluate the expression */
|
||||||
++emsg_skip;
|
++emsg_skip;
|
||||||
str = (char *)eval_to_string((char_u *)buffer, TRUE);
|
str = (char *)eval_to_string((char_u *)buffer, TRUE, FALSE);
|
||||||
--emsg_skip;
|
--emsg_skip;
|
||||||
vim_free(buffer);
|
vim_free(buffer);
|
||||||
if (str == NULL)
|
if (str == NULL)
|
||||||
|
|||||||
@ -873,7 +873,8 @@ msg_split(
|
|||||||
char_u *
|
char_u *
|
||||||
eval_to_string(
|
eval_to_string(
|
||||||
char_u *arg UNUSED,
|
char_u *arg UNUSED,
|
||||||
int dolist UNUSED)
|
int convert UNUSED,
|
||||||
|
int use_simple_function UNUSED)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1599,7 +1600,7 @@ Eval(str)
|
|||||||
PREINIT:
|
PREINIT:
|
||||||
char_u *value;
|
char_u *value;
|
||||||
PPCODE:
|
PPCODE:
|
||||||
value = eval_to_string((char_u *)str, TRUE);
|
value = eval_to_string((char_u *)str, TRUE, FALSE);
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
{
|
{
|
||||||
XPUSHs(sv_2mortal(newSViv(0)));
|
XPUSHs(sv_2mortal(newSViv(0)));
|
||||||
|
|||||||
@ -1397,7 +1397,7 @@ tclvimexpr(
|
|||||||
|
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
expr = Tcl_GetStringFromObj(objv[objn], NULL);
|
expr = Tcl_GetStringFromObj(objv[objn], NULL);
|
||||||
str = (char *)eval_to_string((char_u *)expr, TRUE);
|
str = (char *)eval_to_string((char_u *)expr, TRUE, FALSE);
|
||||||
if (str == NULL)
|
if (str == NULL)
|
||||||
Tcl_SetResult(interp, _("invalid expression"), TCL_STATIC);
|
Tcl_SetResult(interp, _("invalid expression"), TCL_STATIC);
|
||||||
else
|
else
|
||||||
|
|||||||
@ -1711,7 +1711,7 @@ eval_map_expr(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: the evaluation may make "mp" invalid.
|
// Note: the evaluation may make "mp" invalid.
|
||||||
p = eval_to_string(expr, FALSE);
|
p = eval_to_string(expr, FALSE, FALSE);
|
||||||
|
|
||||||
--textlock;
|
--textlock;
|
||||||
--ex_normal_lock;
|
--ex_normal_lock;
|
||||||
|
|||||||
@ -4,7 +4,7 @@ varnumber_T num_modulus(varnumber_T n1, varnumber_T n2, int *failed);
|
|||||||
void eval_init(void);
|
void eval_init(void);
|
||||||
void eval_clear(void);
|
void eval_clear(void);
|
||||||
void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, int skip);
|
void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, int skip);
|
||||||
int eval_to_bool(char_u *arg, int *error, exarg_T *eap, int skip);
|
int eval_to_bool(char_u *arg, int *error, exarg_T *eap, int skip, int use_simple_function);
|
||||||
int eval_expr_valid_arg(typval_T *tv);
|
int eval_expr_valid_arg(typval_T *tv);
|
||||||
funccall_T *eval_expr_get_funccal(typval_T *expr, typval_T *rettv);
|
funccall_T *eval_expr_get_funccal(typval_T *expr, typval_T *rettv);
|
||||||
int eval_expr_typval(typval_T *expr, typval_T *argv, int argc, funccall_T *fc_arg, typval_T *rettv);
|
int eval_expr_typval(typval_T *expr, typval_T *argv, int argc, funccall_T *fc_arg, typval_T *rettv);
|
||||||
@ -15,11 +15,12 @@ void clear_evalarg(evalarg_T *evalarg, exarg_T *eap);
|
|||||||
int skip_expr(char_u **pp, evalarg_T *evalarg);
|
int skip_expr(char_u **pp, evalarg_T *evalarg);
|
||||||
int skip_expr_concatenate(char_u **arg, char_u **start, char_u **end, evalarg_T *evalarg);
|
int skip_expr_concatenate(char_u **arg, char_u **start, char_u **end, evalarg_T *evalarg);
|
||||||
char_u *typval2string(typval_T *tv, int convert);
|
char_u *typval2string(typval_T *tv, int convert);
|
||||||
char_u *eval_to_string_eap(char_u *arg, int convert, exarg_T *eap);
|
char_u *eval_to_string_eap(char_u *arg, int convert, exarg_T *eap, int use_simple_function);
|
||||||
char_u *eval_to_string(char_u *arg, int convert);
|
char_u *eval_to_string(char_u *arg, int convert, int use_simple_function);
|
||||||
char_u *eval_to_string_safe(char_u *arg, int use_sandbox, int keep_script_version);
|
char_u *eval_to_string_safe(char_u *arg, int use_sandbox, int keep_script_version, int use_simple_function);
|
||||||
varnumber_T eval_to_number(char_u *expr);
|
varnumber_T eval_to_number(char_u *expr, int use_simple_function);
|
||||||
typval_T *eval_expr(char_u *arg, exarg_T *eap);
|
typval_T *eval_expr(char_u *arg, exarg_T *eap);
|
||||||
|
typval_T *eval_expr_ext(char_u *arg, exarg_T *eap, int use_simple_function);
|
||||||
int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv);
|
int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv);
|
||||||
void *call_func_retstr(char_u *func, int argc, typval_T *argv);
|
void *call_func_retstr(char_u *func, int argc, typval_T *argv);
|
||||||
void *call_func_retlist(char_u *func, int argc, typval_T *argv);
|
void *call_func_retlist(char_u *func, int argc, typval_T *argv);
|
||||||
@ -38,6 +39,8 @@ char_u *eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext);
|
|||||||
char_u *eval_next_line(char_u *arg, evalarg_T *evalarg);
|
char_u *eval_next_line(char_u *arg, evalarg_T *evalarg);
|
||||||
char_u *skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg);
|
char_u *skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg);
|
||||||
int eval0(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg);
|
int eval0(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg);
|
||||||
|
int may_call_simple_func(char_u *arg, typval_T *rettv);
|
||||||
|
int eval0_simple_funccal(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg);
|
||||||
int eval0_retarg(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg, char_u **retarg);
|
int eval0_retarg(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg, char_u **retarg);
|
||||||
int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
|
||||||
void eval_addblob(typval_T *tv1, typval_T *tv2);
|
void eval_addblob(typval_T *tv1, typval_T *tv2);
|
||||||
|
|||||||
@ -2125,7 +2125,7 @@ vim_regsub_both(
|
|||||||
// Execute instructions from ISN_SUBSTITUTE.
|
// Execute instructions from ISN_SUBSTITUTE.
|
||||||
eval_result[nested] = exe_substitute_instr();
|
eval_result[nested] = exe_substitute_instr();
|
||||||
else
|
else
|
||||||
eval_result[nested] = eval_to_string(source + 2, TRUE);
|
eval_result[nested] = eval_to_string(source + 2, TRUE, FALSE);
|
||||||
--nesting;
|
--nesting;
|
||||||
|
|
||||||
if (eval_result[nested] != NULL)
|
if (eval_result[nested] != NULL)
|
||||||
|
|||||||
@ -151,7 +151,7 @@ get_expr_line(void)
|
|||||||
return expr_copy;
|
return expr_copy;
|
||||||
|
|
||||||
++nested;
|
++nested;
|
||||||
rv = eval_to_string_eap(expr_copy, TRUE, expr_eap);
|
rv = eval_to_string_eap(expr_copy, TRUE, expr_eap, FALSE);
|
||||||
--nested;
|
--nested;
|
||||||
vim_free(expr_copy);
|
vim_free(expr_copy);
|
||||||
return rv;
|
return rv;
|
||||||
|
|||||||
@ -1198,7 +1198,7 @@ get_keymap_str(
|
|||||||
curwin = wp;
|
curwin = wp;
|
||||||
STRCPY(buf, "b:keymap_name"); // must be writable
|
STRCPY(buf, "b:keymap_name"); // must be writable
|
||||||
++emsg_skip;
|
++emsg_skip;
|
||||||
s = p = eval_to_string(buf, FALSE);
|
s = p = eval_to_string(buf, FALSE, FALSE);
|
||||||
--emsg_skip;
|
--emsg_skip;
|
||||||
curbuf = old_curbuf;
|
curbuf = old_curbuf;
|
||||||
curwin = old_curwin;
|
curwin = old_curwin;
|
||||||
@ -2976,7 +2976,7 @@ free_screenlines(void)
|
|||||||
* Clear the screen.
|
* Clear the screen.
|
||||||
* May delay if there is something the user should read.
|
* May delay if there is something the user should read.
|
||||||
* Allocated the screen for resizing if needed.
|
* Allocated the screen for resizing if needed.
|
||||||
* Returns TRUE when the screen was actually claared, FALSE if all display
|
* Returns TRUE when the screen was actually cleared, FALSE if all display
|
||||||
* cells were marked for updating.
|
* cells were marked for updating.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|||||||
@ -810,7 +810,7 @@ load_pack_plugin(char_u *fname)
|
|||||||
|
|
||||||
// If runtime/filetype.vim wasn't loaded yet, the scripts will be
|
// If runtime/filetype.vim wasn't loaded yet, the scripts will be
|
||||||
// found when it loads.
|
// found when it loads.
|
||||||
if (cmd != NULL && eval_to_number(cmd) > 0)
|
if (cmd != NULL && eval_to_number(cmd, FALSE) > 0)
|
||||||
{
|
{
|
||||||
do_cmdline_cmd((char_u *)"augroup filetypedetect");
|
do_cmdline_cmd((char_u *)"augroup filetypedetect");
|
||||||
vim_snprintf((char *)pat, len, ftpat, ffname);
|
vim_snprintf((char *)pat, len, ftpat, ffname);
|
||||||
|
|||||||
@ -938,7 +938,7 @@ fex_format(
|
|||||||
// Evaluate the function.
|
// Evaluate the function.
|
||||||
if (use_sandbox)
|
if (use_sandbox)
|
||||||
++sandbox;
|
++sandbox;
|
||||||
r = (int)eval_to_number(fex);
|
r = (int)eval_to_number(fex, TRUE);
|
||||||
if (use_sandbox)
|
if (use_sandbox)
|
||||||
--sandbox;
|
--sandbox;
|
||||||
|
|
||||||
|
|||||||
@ -699,6 +699,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
634,
|
||||||
/**/
|
/**/
|
||||||
633,
|
633,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user