patch 8.1.1116: cannot enforce a Vim script style
Problem: Cannot enforce a Vim script style.
Solution: Add the :scriptversion command. (closes #3857)
diff --git a/src/eval.c b/src/eval.c
index 78e2c60..9e93dcf 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1249,6 +1249,7 @@
char_u op[2];
char_u *argend;
int first = TRUE;
+ int concat;
argend = skip_var_list(arg, &var_count, &semicolon);
if (argend == NULL)
@@ -1256,14 +1257,19 @@
if (argend > arg && argend[-1] == '.') // for var.='str'
--argend;
expr = skipwhite(argend);
- if (*expr != '=' && !((vim_strchr((char_u *)"+-*/%.", *expr) != NULL
- && expr[1] == '=') || STRNCMP(expr, "..=", 3) == 0))
+ concat = expr[0] == '.'
+ && ((expr[1] == '=' && current_sctx.sc_version < 2)
+ || (expr[1] == '.' && expr[2] == '='));
+ if (*expr != '=' && !((vim_strchr((char_u *)"+-*/%", *expr) != NULL
+ && expr[1] == '=') || concat))
{
/*
* ":let" without "=": list variables
*/
if (*arg == '[')
emsg(_(e_invarg));
+ else if (expr[0] == '.')
+ emsg(_("E985: .= is not supported with script version 2"));
else if (!ends_excmd(*arg))
/* ":let var1 var2" */
arg = list_arg_vars(eap, arg, &first);
@@ -3817,7 +3823,7 @@
* Handle fourth level expression:
* + number addition
* - number subtraction
- * . string concatenation
+ * . string concatenation (if script version is 1)
* .. string concatenation
*
* "arg" must point to the first non-white of the expression.
@@ -3838,6 +3844,7 @@
char_u *s1, *s2;
char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN];
char_u *p;
+ int concat;
/*
* Get the first variable.
@@ -3850,8 +3857,11 @@
*/
for (;;)
{
+ // "." is only string concatenation when scriptversion is 1
op = **arg;
- if (op != '+' && op != '-' && op != '.')
+ concat = op == '.'
+ && (*(*arg + 1) == '.' || current_sctx.sc_version < 2);
+ if (op != '+' && op != '-' && !concat)
break;
if ((op != '+' || (rettv->v_type != VAR_LIST
@@ -4224,6 +4234,17 @@
*arg = skipwhite(*arg + 1);
end_leader = *arg;
+ if (**arg == '.' && (!isdigit(*(*arg + 1))
+#ifdef FEAT_FLOAT
+ || current_sctx.sc_version < 2
+#endif
+ ))
+ {
+ semsg(_(e_invexpr2), *arg);
+ ++*arg;
+ return FAIL;
+ }
+
switch (**arg)
{
/*
@@ -4239,16 +4260,23 @@
case '7':
case '8':
case '9':
+ case '.':
{
#ifdef FEAT_FLOAT
- char_u *p = skipdigits(*arg + 1);
+ char_u *p;
int get_float = FALSE;
/* We accept a float when the format matches
* "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very
* strict to avoid backwards compatibility problems.
+ * With script version 2 and later the leading digit can be
+ * omitted.
* Don't look for a float after the "." operator, so that
* ":let vers = 1.2.3" doesn't fail. */
+ if (**arg == '.')
+ p = *arg;
+ else
+ p = skipdigits(*arg + 1);
if (!want_string && p[0] == '.' && vim_isdigit(p[1]))
{
get_float = TRUE;