# HG changeset patch # User Bram Moolenaar # Date 1569679203 -7200 # Node ID a81f0c936112be719440d5be41d6bc95125bc346 # Parent 52a1ffca4253217f6a487e2db4267ac8f8ca24aa patch 8.1.2092: MS-Windows: redirect in system() does not work Commit: https://github.com/vim/vim/commit/1a613398068580ca1286ac2ed920f20c978aa662 Author: Bram Moolenaar Date: Sat Sep 28 15:51:37 2019 +0200 patch 8.1.2092: MS-Windows: redirect in system() does not work Problem: MS-Windows: redirect in system() does not work. Solution: Handle 'shellxescape' and 'shellxquote' better. (Yasuhiro Matsumoto, closes #2054) diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -1762,12 +1762,21 @@ make_filter_cmd( STRCAT(buf, itmp); } #else - /* - * For shells that don't understand braces around commands, at least allow - * the use of commands in a pipe. - */ - STRCPY(buf, cmd); - if (itmp != NULL) + // For shells that don't understand braces around commands, at least allow + // the use of commands in a pipe. + if (*p_sxe != NUL && *p_sxq == '(') + { + if (itmp != NULL || otmp != NULL) + vim_snprintf((char *)buf, len, "(%s)", (char *)cmd); + else + STRCPY(buf, cmd); + if (itmp != NULL) + { + STRCAT(buf, " < "); + STRCAT(buf, itmp); + } + } + else { char_u *p; @@ -1819,18 +1828,20 @@ append_redir( char_u *end; end = buf + STRLEN(buf); - /* find "%s" */ + // find "%s" for (p = opt; (p = vim_strchr(p, '%')) != NULL; ++p) { - if (p[1] == 's') /* found %s */ + if (p[1] == 's') // found %s break; - if (p[1] == '%') /* skip %% */ + if (p[1] == '%') // skip %% ++p; } if (p != NULL) { - *end = ' '; /* not really needed? Not with sh, ksh or bash */ - vim_snprintf((char *)end + 1, (size_t)(buflen - (end + 1 - buf)), +#ifdef MSWIN + *end++ = ' '; // not really needed? Not with sh, ksh or bash +#endif + vim_snprintf((char *)end, (size_t)(buflen - (end - buf)), (char *)opt, (char *)fname); } else @@ -1838,7 +1849,7 @@ append_redir( #ifdef FEAT_QUICKFIX " %s %s", #else - " %s%s", /* " > %s" causes problems on Amiga */ + " %s%s", // " > %s" causes problems on Amiga #endif (char *)opt, (char *)fname); } diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -3157,7 +3157,7 @@ call_shell(char_u *cmd, int opt) { char_u *ecmd = cmd; - if (*p_sxe != NUL && STRCMP(p_sxq, "(") == 0) + if (*p_sxe != NUL && *p_sxq == '(') { ecmd = vim_strsave_escaped_ext(cmd, p_sxe, '^', FALSE); if (ecmd == NULL) @@ -3168,11 +3168,11 @@ call_shell(char_u *cmd, int opt) { STRCPY(ncmd, p_sxq); STRCAT(ncmd, ecmd); - /* When 'shellxquote' is ( append ). - * When 'shellxquote' is "( append )". */ - STRCAT(ncmd, STRCMP(p_sxq, "(") == 0 ? (char_u *)")" - : STRCMP(p_sxq, "\"(") == 0 ? (char_u *)")\"" - : p_sxq); + // When 'shellxquote' is ( append ). + // When 'shellxquote' is "( append )". + STRCAT(ncmd, *p_sxq == '(' ? (char_u *)")" + : *p_sxq == '"' && *(p_sxq+1) == '(' ? (char_u *)")\"" + : p_sxq); retval = mch_call_shell(ncmd, opt); vim_free(ncmd); } diff --git a/src/testdir/test_system.vim b/src/testdir/test_system.vim --- a/src/testdir/test_system.vim +++ b/src/testdir/test_system.vim @@ -3,9 +3,24 @@ source shared.vim func Test_System() - if !executable('echo') || !executable('cat') || !executable('wc') + if !has('win32') + call assert_equal("123\n", system('echo 123')) + call assert_equal(['123'], systemlist('echo 123')) + call assert_equal('123', system('cat', '123')) + call assert_equal(['123'], systemlist('cat', '123')) + call assert_equal(["as\df"], systemlist('cat', ["as\df"])) + else + call assert_equal("123\n", system('echo 123')) + call assert_equal(["123\r"], systemlist('echo 123')) + call assert_equal("123", system('more', '123')) + call assert_equal(["123"], systemlist('more', '123')) + call assert_equal(["as\df"], systemlist('more', ["as\df"])) + endif + + if !executable('cat') || !executable('wc') return endif + let out = 'echo 123'->system() " On Windows we may get a trailing space. if out != "123 \n" @@ -13,14 +28,17 @@ func Test_System() endif let out = 'echo 123'->systemlist() - " On Windows we may get a trailing space and CR. - if out != ["123 \r"] - call assert_equal(['123'], out) + if !has('win32') + call assert_equal(["123"], out) + else + call assert_equal(["123\r"], out) endif - call assert_equal('123', system('cat', '123')) - call assert_equal(['123'], systemlist('cat', '123')) - call assert_equal(["as\df"], systemlist('cat', ["as\df"])) + if executable('cat') + call assert_equal('123', system('cat', '123')) + call assert_equal(['123'], systemlist('cat', '123')) + call assert_equal(["as\df"], systemlist('cat', ["as\df"])) + endif new Xdummy call setline(1, ['asdf', "pw\er", 'xxxx']) @@ -39,9 +57,11 @@ func Test_System() call assert_equal(['3'], out) endif - let out = systemlist('cat', bufnr('%')) - " On Windows we may get a trailing CR. - if out != ["asdf\r", "pw\er\r", "xxxx\r"] + if !has('win32') + let out = systemlist('cat', bufnr('%')) + call assert_equal(['asdf', "pw\er", 'xxxx'], out) + else + let out = systemlist('more', bufnr('%')) call assert_equal(['asdf', "pw\er", 'xxxx'], out) endif bwipe! diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2092, +/**/ 2091, /**/ 2090,