Patch 8.2.2652
Problem: Vim9: can use command modifier without an effect.
Solution: Give an error for a misplaced command modifier. Fix error message
number.
Files: src/vim9compile.c, src/ex_docmd.c, src/proto/ex_docmd.pro,
src/ex_eval.c, src/testdir/test_vim9_cmd.vim,
src/testdir/test_vim9_builtin.vim,
src/testdir/test_vim9_disassemble.vim
*** ../vim-8.2.2651/src/vim9compile.c 2021-03-25 21:12:09.902618807 +0100
--- src/vim9compile.c 2021-03-25 22:09:16.377074112 +0100
***************
*** 2142,2152 ****
{
isn_T *isn;
! if (cmod->cmod_flags != 0
! || cmod->cmod_split != 0
! || cmod->cmod_verbose != 0
! || cmod->cmod_tab != 0
! || cmod->cmod_filter_regmatch.regprog != NULL)
{
cctx->ctx_has_cmdmod = TRUE;
--- 2142,2148 ----
{
isn_T *isn;
! if (has_cmdmod(cmod))
{
cctx->ctx_has_cmdmod = TRUE;
***************
*** 2172,2193 ****
return OK;
}
! /*
! * If an ISN_CMDMOD was just generated drop it.
! */
! static void
! drop_cmdmod(cctx_T *cctx)
{
garray_T *instr = &cctx->ctx_instr;
- // Drop any CMDMOD instruction
if (cctx->ctx_has_cmdmod
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1].isn_type
== ISN_CMDMOD)
{
! --instr->ga_len;
! cctx->ctx_has_cmdmod = FALSE;
}
}
/*
--- 2168,2186 ----
return OK;
}
! static int
! misplaced_cmdmod(cctx_T *cctx)
{
garray_T *instr = &cctx->ctx_instr;
if (cctx->ctx_has_cmdmod
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1].isn_type
== ISN_CMDMOD)
{
! emsg(_(e_misplaced_command_modifier));
! return TRUE;
}
+ return FALSE;
}
/*
***************
*** 7147,7153 ****
garray_T *instr = &cctx->ctx_instr;
isn_T *isn;
! drop_cmdmod(cctx);
if (scope == NULL || scope->se_type != IF_SCOPE)
{
emsg(_(e_endif_without_if));
--- 7140,7148 ----
garray_T *instr = &cctx->ctx_instr;
isn_T *isn;
! if (misplaced_cmdmod(cctx))
! return NULL;
!
if (scope == NULL || scope->se_type != IF_SCOPE)
{
emsg(_(e_endif_without_if));
***************
*** 7393,7399 ****
forscope_T *forscope;
isn_T *isn;
! drop_cmdmod(cctx);
if (scope == NULL || scope->se_type != FOR_SCOPE)
{
--- 7388,7395 ----
forscope_T *forscope;
isn_T *isn;
! if (misplaced_cmdmod(cctx))
! return NULL;
if (scope == NULL || scope->se_type != FOR_SCOPE)
{
***************
*** 7479,7485 ****
scope_T *scope = cctx->ctx_scope;
garray_T *instr = &cctx->ctx_instr;
! drop_cmdmod(cctx);
if (scope == NULL || scope->se_type != WHILE_SCOPE)
{
emsg(_(e_while));
--- 7475,7482 ----
scope_T *scope = cctx->ctx_scope;
garray_T *instr = &cctx->ctx_instr;
! if (misplaced_cmdmod(cctx))
! return NULL;
if (scope == NULL || scope->se_type != WHILE_SCOPE)
{
emsg(_(e_while));
***************
*** 7644,7649 ****
--- 7641,7649 ----
scope_T *try_scope;
scope_T *scope;
+ if (misplaced_cmdmod(cctx))
+ return NULL;
+
// scope that holds the jumps that go to catch/finally/endtry
try_scope = new_scope(cctx, TRY_SCOPE);
if (try_scope == NULL)
***************
*** 7684,7689 ****
--- 7684,7692 ----
char_u *p;
isn_T *isn;
+ if (misplaced_cmdmod(cctx))
+ return NULL;
+
// end block scope from :try or :catch
if (scope != NULL && scope->se_type == BLOCK_SCOPE)
compile_endblock(cctx);
***************
*** 7796,7801 ****
--- 7799,7807 ----
isn_T *isn;
int this_instr;
+ if (misplaced_cmdmod(cctx))
+ return NULL;
+
// end block scope from :try or :catch
if (scope != NULL && scope->se_type == BLOCK_SCOPE)
compile_endblock(cctx);
***************
*** 7854,7859 ****
--- 7860,7868 ----
garray_T *instr = &cctx->ctx_instr;
isn_T *try_isn;
+ if (misplaced_cmdmod(cctx))
+ return NULL;
+
// end block scope from :catch or :finally
if (scope != NULL && scope->se_type == BLOCK_SCOPE)
compile_endblock(cctx);
*** ../vim-8.2.2651/src/ex_docmd.c 2021-03-20 14:59:58.508414399 +0100
--- src/ex_docmd.c 2021-03-25 22:01:28.754365727 +0100
***************
*** 2970,2975 ****
--- 2970,3002 ----
}
/*
+ * Return TRUE if "cmod" has anything set.
+ */
+ int
+ has_cmdmod(cmdmod_T *cmod)
+ {
+ return cmod->cmod_flags != 0
+ || cmod->cmod_split != 0
+ || cmod->cmod_verbose != 0
+ || cmod->cmod_tab != 0
+ || cmod->cmod_filter_regmatch.regprog != NULL;
+ }
+
+ /*
+ * If Vim9 script and "cmdmod" has anything set give an error and return TRUE.
+ */
+ int
+ cmdmod_error(void)
+ {
+ if (in_vim9script() && has_cmdmod(&cmdmod))
+ {
+ emsg(_(e_misplaced_command_modifier));
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ /*
* Apply the command modifiers. Saves current state in "cmdmod", call
* undo_cmdmod() later.
*/
*** ../vim-8.2.2651/src/proto/ex_docmd.pro 2021-03-14 13:21:31.785065163
+0100
--- src/proto/ex_docmd.pro 2021-03-25 22:01:34.286350222 +0100
***************
*** 8,13 ****
--- 8,15 ----
char_u *getline_peek(char_u *(*fgetline)(int, void *, int, getline_opt_T),
void *cookie);
char *ex_errmsg(char *msg, char_u *arg);
int parse_command_modifiers(exarg_T *eap, char **errormsg, cmdmod_T *cmod,
int skip_only);
+ int has_cmdmod(cmdmod_T *cmod);
+ int cmdmod_error(void);
void apply_cmdmod(cmdmod_T *cmod);
void undo_cmdmod(cmdmod_T *cmod);
int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
*** ../vim-8.2.2651/src/ex_eval.c 2021-02-26 22:21:19.082675454 +0100
--- src/ex_eval.c 2021-03-25 22:08:59.889119166 +0100
***************
*** 1011,1016 ****
--- 1011,1018 ----
{
cstack_T *cstack = eap->cstack;
+ if (cmdmod_error())
+ return;
did_endif = TRUE;
if (cstack->cs_idx < 0
|| (cstack->cs_flags[cstack->cs_idx]
***************
*** 1314,1319 ****
--- 1316,1324 ----
int csf;
int fl;
+ if (cmdmod_error())
+ return;
+
if (eap->cmdidx == CMD_endwhile)
{
err = e_while;
***************
*** 1539,1544 ****
--- 1544,1552 ----
int skip;
cstack_T *cstack = eap->cstack;
+ if (cmdmod_error())
+ return;
+
if (cstack->cs_idx == CSTACK_LEN - 1)
eap->errmsg = _("E601: :try nesting too deep");
else
***************
*** 1617,1622 ****
--- 1625,1633 ----
cstack_T *cstack = eap->cstack;
char_u *pat;
+ if (cmdmod_error())
+ return;
+
if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
{
eap->errmsg = _(e_catch);
***************
*** 1777,1782 ****
--- 1788,1796 ----
int pending = CSTP_NONE;
cstack_T *cstack = eap->cstack;
+ if (cmdmod_error())
+ return;
+
if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
eap->errmsg = _(e_finally);
else
***************
*** 1906,1911 ****
--- 1920,1928 ----
void *rettv = NULL;
cstack_T *cstack = eap->cstack;
+ if (cmdmod_error())
+ return;
+
if (cstack->cs_trylevel <= 0 || cstack->cs_idx < 0)
eap->errmsg = _(e_no_endtry);
else
*** ../vim-8.2.2651/src/testdir/test_vim9_cmd.vim 2021-03-24
20:08:08.540745895 +0100
--- src/testdir/test_vim9_cmd.vim 2021-03-25 22:09:42.493002797 +0100
***************
*** 797,802 ****
--- 797,851 ----
bwipe!
enddef
+ def Test_useless_command_modifier()
+ g:maybe = true
+ var lines =<< trim END
+ if g:maybe
+ silent endif
+ END
+ CheckDefAndScriptFailure(lines, 'E1176:', 2)
+
+ lines =<< trim END
+ for i in [0]
+ silent endfor
+ END
+ CheckDefAndScriptFailure(lines, 'E1176:', 2)
+
+ lines =<< trim END
+ while g:maybe
+ silent endwhile
+ END
+ CheckDefAndScriptFailure(lines, 'E1176:', 2)
+
+ lines =<< trim END
+ silent try
+ finally
+ endtry
+ END
+ CheckDefAndScriptFailure(lines, 'E1176:', 1)
+
+ lines =<< trim END
+ try
+ silent catch
+ endtry
+ END
+ CheckDefAndScriptFailure(lines, 'E1176:', 2)
+
+ lines =<< trim END
+ try
+ silent finally
+ endtry
+ END
+ CheckDefAndScriptFailure(lines, 'E1176:', 2)
+
+ lines =<< trim END
+ try
+ finally
+ silent endtry
+ END
+ CheckDefAndScriptFailure(lines, 'E1176:', 3)
+ enddef
+
def Test_eval_command()
var from = 3
var to = 5
*** ../vim-8.2.2651/src/testdir/test_vim9_builtin.vim 2021-03-22
22:21:22.781399262 +0100
--- src/testdir/test_vim9_builtin.vim 2021-03-25 22:12:34.912533393 +0100
***************
*** 247,253 ****
def Test_exepath()
CheckDefExecFailure(['echo exepath(true)'], 'E1174:')
CheckDefExecFailure(['echo exepath(v:null)'], 'E1174:')
! CheckDefExecFailure(['echo exepath("")'], 'E1142:')
enddef
def Test_expand()
--- 247,253 ----
def Test_exepath()
CheckDefExecFailure(['echo exepath(true)'], 'E1174:')
CheckDefExecFailure(['echo exepath(v:null)'], 'E1174:')
! CheckDefExecFailure(['echo exepath("")'], 'E1175:')
enddef
def Test_expand()
***************
*** 406,418 ****
def Test_finddir()
CheckDefExecFailure(['echo finddir(true)'], 'E1174:')
CheckDefExecFailure(['echo finddir(v:null)'], 'E1174:')
! CheckDefExecFailure(['echo finddir("")'], 'E1142:')
enddef
def Test_findfile()
CheckDefExecFailure(['echo findfile(true)'], 'E1174:')
CheckDefExecFailure(['echo findfile(v:null)'], 'E1174:')
! CheckDefExecFailure(['echo findfile("")'], 'E1142:')
enddef
def Test_flattennew()
--- 406,418 ----
def Test_finddir()
CheckDefExecFailure(['echo finddir(true)'], 'E1174:')
CheckDefExecFailure(['echo finddir(v:null)'], 'E1174:')
! CheckDefExecFailure(['echo finddir("")'], 'E1175:')
enddef
def Test_findfile()
CheckDefExecFailure(['echo findfile(true)'], 'E1174:')
CheckDefExecFailure(['echo findfile(v:null)'], 'E1174:')
! CheckDefExecFailure(['echo findfile("")'], 'E1175:')
enddef
def Test_flattennew()
*** ../vim-8.2.2651/src/testdir/test_vim9_disassemble.vim 2021-03-25
21:12:09.902618807 +0100
--- src/testdir/test_vim9_disassemble.vim 2021-03-25 22:13:42.944348686
+0100
***************
*** 1903,1909 ****
def s:SilentIf()
silent if 4 == g:five
silent elseif 4 == g:five
! silent endif
enddef
def Test_silent_if()
--- 1903,1909 ----
def s:SilentIf()
silent if 4 == g:five
silent elseif 4 == g:five
! endif
enddef
def Test_silent_if()
***************
*** 1924,1937 ****
'\d\+ COMPAREANY ==\_s*' ..
'\d\+ CMDMOD_REV\_s*' ..
'\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
! 'silent endif\_s*' ..
'\d\+ RETURN 0',
res)
enddef
def s:SilentFor()
silent for i in [0]
! silent endfor
enddef
def Test_silent_for()
--- 1924,1937 ----
'\d\+ COMPAREANY ==\_s*' ..
'\d\+ CMDMOD_REV\_s*' ..
'\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
! 'endif\_s*' ..
'\d\+ RETURN 0',
res)
enddef
def s:SilentFor()
silent for i in [0]
! endfor
enddef
def Test_silent_for()
***************
*** 1945,1951 ****
'\d CMDMOD_REV\_s*' ..
'5 FOR $0 -> 8\_s*' ..
'\d STORE $1\_s*' ..
! 'silent endfor\_s*' ..
'\d JUMP -> 5\_s*' ..
'8 DROP\_s*' ..
'\d RETURN 0\_s*',
--- 1945,1951 ----
'\d CMDMOD_REV\_s*' ..
'5 FOR $0 -> 8\_s*' ..
'\d STORE $1\_s*' ..
! 'endfor\_s*' ..
'\d JUMP -> 5\_s*' ..
'8 DROP\_s*' ..
'\d RETURN 0\_s*',
***************
*** 1954,1960 ****
def s:SilentWhile()
silent while g:not
! silent endwhile
enddef
def Test_silent_while()
--- 1954,1960 ----
def s:SilentWhile()
silent while g:not
! endwhile
enddef
def Test_silent_while()
***************
*** 1967,1973 ****
'\d CMDMOD_REV\_s*' ..
'\d JUMP_IF_FALSE -> 6\_s*' ..
! 'silent endwhile\_s*' ..
'\d JUMP -> 0\_s*' ..
'6 RETURN 0\_s*',
res)
--- 1967,1973 ----
'\d CMDMOD_REV\_s*' ..
'\d JUMP_IF_FALSE -> 6\_s*' ..
! 'endwhile\_s*' ..
'\d JUMP -> 0\_s*' ..
'6 RETURN 0\_s*',
res)
*** ../vim-8.2.2651/src/version.c 2021-03-25 21:12:09.902618807 +0100
--- src/version.c 2021-03-25 21:48:20.000683734 +0100
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2652,
/**/
--
How To Keep A Healthy Level Of Insanity:
7. Finish all your sentences with "in accordance with the prophecy".
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/202103252116.12PLG4LB155344%40masaka.moolenaar.net.