# HG changeset patch # User Bram Moolenaar # Date 1596618008 -7200 # Node ID 3c6c52fbc8ea598e4c003ad45a0203a764f4b472 # Parent 87a1c471781723341da2d44fb39fb79b6a70088c patch 8.2.1365: Vim9: no error for missing white space around operator Commit: https://github.com/vim/vim/commit/bb1b5e24ecc0abe1fee164e9de13796989eff784 Author: Bram Moolenaar Date: Wed Aug 5 10:53:21 2020 +0200 patch 8.2.1365: Vim9: no error for missing white space around operator Problem: Vim9: no error for missing white space around operator. Solution: Check for white space. (closes https://github.com/vim/vim/issues/6618) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -2574,6 +2574,7 @@ eval5(char_u **arg, typval_T *rettv, eva int getnext; char_u *p; int op; + int oplen; int concat; typval_T var2; @@ -2584,11 +2585,19 @@ eval5(char_u **arg, typval_T *rettv, eva if (op != '+' && op != '-' && !concat) break; + evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE); if (getnext) *arg = eval_next_line(evalarg); else + { + if (evaluate && in_vim9script() && !VIM_ISWHITE(**arg)) + { + error_white_both(p, 1); + clear_tv(rettv); + return FAIL; + } *arg = p; - evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE); + } if ((op != '+' || (rettv->v_type != VAR_LIST && rettv->v_type != VAR_BLOB)) #ifdef FEAT_FLOAT @@ -2613,9 +2622,14 @@ eval5(char_u **arg, typval_T *rettv, eva /* * Get the second variable. */ - if (op == '.' && *(*arg + 1) == '.') // .. string concatenation - ++*arg; - *arg = skipwhite_and_linebreak(*arg + 1, evalarg); + oplen = (op == '.' && *(*arg + 1) == '.') ? 2 : 1; + if (evaluate && in_vim9script() && !IS_WHITE_OR_NUL((*arg)[oplen])) + { + error_white_both(p, oplen); + clear_tv(rettv); + return FAIL; + } + *arg = skipwhite_and_linebreak(*arg + oplen, evalarg); if (eval6(arg, &var2, evalarg, op == '.') == FAIL) { clear_tv(rettv); @@ -3358,6 +3372,7 @@ eval_method( } else { + *arg = skipwhite(*arg); if (**arg != '(') { if (verbose) @@ -4841,7 +4856,7 @@ get_env_len(char_u **arg) /* * Get the length of the name of a function or internal variable. - * "arg" is advanced to the first non-white character after the name. + * "arg" is advanced to after the name. * Return 0 if something is wrong. */ int @@ -4867,7 +4882,7 @@ get_id_len(char_u **arg) return 0; len = (int)(p - *arg); - *arg = skipwhite(p); + *arg = p; return len; } diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -1137,6 +1137,7 @@ list_arg_vars(exarg_T *eap, char_u *arg, } else { + arg = skipwhite(arg); if (tofree != NULL) name = tofree; if (eval_variable(name, len, &tv, NULL, TRUE, FALSE) == FAIL) @@ -3358,6 +3359,7 @@ assert_error(garray_T *gap) int var_exists(char_u *var) { + char_u *arg = var; char_u *name; char_u *tofree; typval_T tv; @@ -3366,7 +3368,7 @@ var_exists(char_u *var) // get_name_len() takes care of expanding curly braces name = var; - len = get_name_len(&var, &tofree, TRUE, FALSE); + len = get_name_len(&arg, &tofree, TRUE, FALSE); if (len > 0) { if (tofree != NULL) @@ -3375,12 +3377,13 @@ var_exists(char_u *var) if (n) { // handle d.key, l[idx], f(expr) - n = (handle_subscript(&var, &tv, &EVALARG_EVALUATE, FALSE) == OK); + arg = skipwhite(arg); + n = (handle_subscript(&arg, &tv, &EVALARG_EVALUATE, FALSE) == OK); if (n) clear_tv(&tv); } } - if (*var != NUL) + if (*arg != NUL) n = FALSE; vim_free(tofree); diff --git a/src/proto/vim9compile.pro b/src/proto/vim9compile.pro --- a/src/proto/vim9compile.pro +++ b/src/proto/vim9compile.pro @@ -17,6 +17,7 @@ char_u *peek_next_line_from_context(cctx char_u *next_line_from_context(cctx_T *cctx, int skip_comment); char_u *to_name_const_end(char_u *arg); exptype_T get_compare_type(char_u *p, int *len, int *type_is); +void error_white_both(char_u *op, int len); int assignment_len(char_u *p, int *heredoc); void vim9_declare_error(char_u *name); int check_vim9_unlet(char_u *name); diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -872,6 +872,39 @@ def Test_expr5_vim9script() echo 'abc' isnot? 'abc' END CheckScriptFailure(lines, 'E15:') + + # check white space + lines =<< trim END + vim9script + echo 5+6 + END + CheckScriptFailure(lines, 'E1004:') + lines =<< trim END + vim9script + echo 5 +6 + END + CheckScriptFailure(lines, 'E1004:') + lines =<< trim END + vim9script + echo 5+ 6 + END + CheckScriptFailure(lines, 'E1004:') + + lines =<< trim END + vim9script + echo 'a'..'b' + END + CheckScriptFailure(lines, 'E1004:') + lines =<< trim END + vim9script + echo 'a' ..'b' + END + CheckScriptFailure(lines, 'E1004:') + lines =<< trim END + vim9script + echo 'a'.. 'b' + END + CheckScriptFailure(lines, 'E1004:') enddef def Test_expr5_float() diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -1270,7 +1270,7 @@ enddef def TreeWalk(dir: string): list return readdir(dir)->map({_, val -> fnamemodify(dir .. '/' .. val, ':p')->isdirectory() - ? {val : TreeWalk(dir .. '/' .. val)} + ? {val: TreeWalk(dir .. '/' .. val)} : val }) enddef diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1365, +/**/ 1364, /**/ 1363, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -4244,6 +4244,18 @@ compile_expr7( } /* + * Give the "white on both sides" error, taking the operator from "p[len]". + */ + void +error_white_both(char_u *op, int len) +{ + char_u buf[10]; + + vim_strncpy(buf, op, len); + semsg(_(e_white_both), buf); +} + +/* * * number multiplication * / number division * % number modulo @@ -4275,10 +4287,7 @@ compile_expr6(char_u **arg, cctx_T *cctx if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[1])) { - char_u buf[3]; - - vim_strncpy(buf, op, 1); - semsg(_(e_white_both), buf); + error_white_both(op, 1); return FAIL; } *arg = skipwhite(op + 1); @@ -4354,10 +4363,7 @@ compile_expr5(char_u **arg, cctx_T *cctx if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(op[oplen])) { - char_u buf[3]; - - vim_strncpy(buf, op, oplen); - semsg(_(e_white_both), buf); + error_white_both(op, oplen); return FAIL; } @@ -4486,10 +4492,7 @@ compile_expr4(char_u **arg, cctx_T *cctx if (!IS_WHITE_OR_NUL(**arg) || !IS_WHITE_OR_NUL(p[len])) { - char_u buf[7]; - - vim_strncpy(buf, p, len); - semsg(_(e_white_both), buf); + error_white_both(p, len); return FAIL; } @@ -5132,10 +5135,7 @@ compile_assignment(char_u *arg, exarg_T if (oplen > 0 && (!VIM_ISWHITE(*sp) || !VIM_ISWHITE(op[oplen]))) { - char_u buf[4]; - - vim_strncpy(buf, op, oplen); - semsg(_(e_white_both), buf); + error_white_both(op, oplen); return NULL; }