aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoroni-link <knil.ino@gmail.com>2014-04-12 23:04:49 +0200
committerThiago de Arruda <tpadilha84@gmail.com>2014-04-14 09:54:40 -0300
commita881273dad5eb5d1f5efa8da79704c9cf9abf0e0 (patch)
tree4c4fc1aeb736aae65758d0cce609f719c7042d37 /src
parent644ccdafe01df76c47f2a6c74a4a55f64602e3db (diff)
downloadrneovim-a881273dad5eb5d1f5efa8da79704c9cf9abf0e0.tar.gz
rneovim-a881273dad5eb5d1f5efa8da79704c9cf9abf0e0.tar.bz2
rneovim-a881273dad5eb5d1f5efa8da79704c9cf9abf0e0.zip
vim-patch:7.4.191
Problem: Escaping a file name for shell commands can't be done without a function. Solution: Add the :S file name modifier. https://code.google.com/p/vim/source/detail?r=40f18a1c1592c8b4047f6f2a413557f48a99c55f
Diffstat (limited to 'src')
-rw-r--r--src/eval.c10
-rw-r--r--src/misc2.c13
-rw-r--r--src/misc2.h2
-rw-r--r--src/normal.c6
-rw-r--r--src/testdir/Makefile2
-rw-r--r--src/testdir/test105.in45
-rw-r--r--src/testdir/test105.ok29
-rw-r--r--src/version.c2
8 files changed, 95 insertions, 14 deletions
diff --git a/src/eval.c b/src/eval.c
index 6b6d25ac3e..187a7014b2 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -13715,7 +13715,7 @@ static void f_sha256(typval_T *argvars, typval_T *rettv)
static void f_shellescape(typval_T *argvars, typval_T *rettv)
{
rettv->vval.v_string = vim_strsave_shellescape(
- get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]));
+ get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]), true);
rettv->v_type = VAR_STRING;
}
@@ -19645,6 +19645,14 @@ repeat:
}
}
+ if (src[*usedlen] == ':' && src[*usedlen + 1] == 'S') {
+ p = vim_strsave_shellescape(*fnamep, false, false);
+ vim_free(*bufp);
+ *bufp = *fnamep = p;
+ *fnamelen = (int)STRLEN(p);
+ *usedlen += 2;
+ }
+
return valid;
}
diff --git a/src/misc2.c b/src/misc2.c
index 997fafc7ff..7b471a5811 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -691,11 +691,12 @@ int csh_like_shell(void)
* This uses single quotes, except when we know we need to use double quotes
* (MS-DOS and MS-Windows without 'shellslash' set).
* Escape a newline, depending on the 'shell' option.
- * When "do_special" is TRUE also replace "!", "%", "#" and things starting
+ * When "do_special" is true also replace "!", "%", "#" and things starting
* with "<" like "<cfile>".
- * Returns the result in allocated memory, NULL if we have run out.
+ * When "do_newline" is false do not escape newline unless it is csh shell.
+ * Returns the result in allocated memory.
*/
-char_u *vim_strsave_shellescape(char_u *string, int do_special)
+char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline)
{
unsigned length;
char_u *p;
@@ -715,7 +716,8 @@ char_u *vim_strsave_shellescape(char_u *string, int do_special)
for (p = string; *p != NUL; mb_ptr_adv(p)) {
if (*p == '\'')
length += 3; /* ' => '\'' */
- if (*p == '\n' || (*p == '!' && (csh_like || do_special))) {
+ if ((*p == '\n' && (csh_like || do_newline))
+ || (*p == '!' && (csh_like || do_special))) {
++length; /* insert backslash */
if (csh_like && do_special)
++length; /* insert backslash */
@@ -742,7 +744,8 @@ char_u *vim_strsave_shellescape(char_u *string, int do_special)
++p;
continue;
}
- if (*p == '\n' || (*p == '!' && (csh_like || do_special))) {
+ if ((*p == '\n' && (csh_like || do_newline))
+ || (*p == '!' && (csh_like || do_special))) {
*d++ = '\\';
if (csh_like && do_special)
*d++ = '\\';
diff --git a/src/misc2.h b/src/misc2.h
index 4013c6b99e..4762af08a9 100644
--- a/src/misc2.h
+++ b/src/misc2.h
@@ -31,7 +31,7 @@ char_u *vim_strsave_escaped_ext(char_u *string, char_u *esc_chars,
int cc,
int bsl);
int csh_like_shell(void);
-char_u *vim_strsave_shellescape(char_u *string, int do_special);
+char_u *vim_strsave_shellescape(char_u *string, bool do_special, bool do_newline);
char_u *vim_strsave_up(char_u *string);
char_u *vim_strnsave_up(char_u *string, int len);
void vim_strup(char_u *p);
diff --git a/src/normal.c b/src/normal.c
index 6aab7a9d3d..094bb9fe94 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -4493,12 +4493,8 @@ static void nv_ident(cmdarg_T *cap)
if (cmdchar == 'K' && !kp_help) {
/* Escape the argument properly for a shell command */
ptr = vim_strnsave(ptr, n);
- p = vim_strsave_shellescape(ptr, TRUE);
+ p = vim_strsave_shellescape(ptr, true, true);
vim_free(ptr);
- if (p == NULL) {
- vim_free(buf);
- return;
- }
newbuf = (char_u *)xrealloc(buf, STRLEN(buf) + STRLEN(p) + 1);
buf = newbuf;
STRCAT(buf, p);
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
index e2e6850ec9..7038bf929c 100644
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -26,7 +26,7 @@ SCRIPTS := test1.out test2.out test3.out test4.out test5.out test6.out \
test89.out test90.out test91.out test92.out test93.out \
test94.out test95.out test96.out test97.out test98.out \
test99.out test100.out test101.out test102.out test103.out \
- test104.out test106.out
+ test104.out test105.out test106.out
SCRIPTS_GUI := test16.out
diff --git a/src/testdir/test105.in b/src/testdir/test105.in
new file mode 100644
index 0000000000..284f3bf4eb
--- /dev/null
+++ b/src/testdir/test105.in
@@ -0,0 +1,45 @@
+Test filename modifiers vim: set ft=vim :
+
+STARTTEST
+:source small.vim
+:%delete _
+:set shell=sh
+:set shellslash
+:let tab="\t"
+:command -nargs=1 Put :let expr=<q-args> | $put =expr.tab.strtrans(string(eval(expr)))
+:let $HOME=fnamemodify('.', ':p:h:h:h')
+:Put fnamemodify('.', ':p' )[-1:]
+:Put fnamemodify('.', ':p:h' )[-1:]
+:Put fnamemodify('test.out', ':p' )[-1:]
+:Put fnamemodify('test.out', ':.' )
+:Put fnamemodify('../testdir/a', ':.' )
+:Put fnamemodify('test.out', ':~' )
+:Put fnamemodify('../testdir/a', ':~' )
+:Put fnamemodify('../testdir/a', ':t' )
+:Put fnamemodify('.', ':p:t' )
+:Put fnamemodify('test.out', ':p:t' )
+:Put fnamemodify('test.out', ':p:e' )
+:Put fnamemodify('test.out', ':p:t:e' )
+:Put fnamemodify('abc.fb2.tar.gz', ':r' )
+:Put fnamemodify('abc.fb2.tar.gz', ':r:r' )
+:Put fnamemodify('abc.fb2.tar.gz', ':r:r:r' )
+:Put substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(src/testdir/.*\)', '\1', '')
+:Put fnamemodify('abc.fb2.tar.gz', ':e' )
+:Put fnamemodify('abc.fb2.tar.gz', ':e:e' )
+:Put fnamemodify('abc.fb2.tar.gz', ':e:e:e' )
+:Put fnamemodify('abc.fb2.tar.gz', ':e:e:e:e')
+:Put fnamemodify('abc.fb2.tar.gz', ':e:e:r' )
+:Put fnamemodify('abc def', ':S' )
+:Put fnamemodify('abc" "def', ':S' )
+:Put fnamemodify('abc"%"def', ':S' )
+:Put fnamemodify('abc'' ''def', ':S' )
+:Put fnamemodify('abc''%''def', ':S' )
+:Put fnamemodify("abc\ndef", ':S' )
+:set shell=tcsh
+:Put fnamemodify("abc\ndef", ':S' )
+:$put ='vim: ts=8'
+:1 delete _
+:w! test.out
+:qa!
+ENDTEST
+
diff --git a/src/testdir/test105.ok b/src/testdir/test105.ok
new file mode 100644
index 0000000000..0681597c05
--- /dev/null
+++ b/src/testdir/test105.ok
@@ -0,0 +1,29 @@
+fnamemodify('.', ':p' )[-1:] '/'
+fnamemodify('.', ':p:h' )[-1:] 'r'
+fnamemodify('test.out', ':p' )[-1:] 't'
+fnamemodify('test.out', ':.' ) 'test.out'
+fnamemodify('../testdir/a', ':.' ) 'a'
+fnamemodify('test.out', ':~' ) '~/src/testdir/test.out'
+fnamemodify('../testdir/a', ':~' ) '~/src/testdir/a'
+fnamemodify('../testdir/a', ':t' ) 'a'
+fnamemodify('.', ':p:t' ) ''
+fnamemodify('test.out', ':p:t' ) 'test.out'
+fnamemodify('test.out', ':p:e' ) 'out'
+fnamemodify('test.out', ':p:t:e' ) 'out'
+fnamemodify('abc.fb2.tar.gz', ':r' ) 'abc.fb2.tar'
+fnamemodify('abc.fb2.tar.gz', ':r:r' ) 'abc.fb2'
+fnamemodify('abc.fb2.tar.gz', ':r:r:r' ) 'abc'
+substitute(fnamemodify('abc.fb2.tar.gz', ':p:r:r'), '.*\(src/testdir/.*\)', '\1', '') 'src/testdir/abc.fb2'
+fnamemodify('abc.fb2.tar.gz', ':e' ) 'gz'
+fnamemodify('abc.fb2.tar.gz', ':e:e' ) 'tar.gz'
+fnamemodify('abc.fb2.tar.gz', ':e:e:e' ) 'fb2.tar.gz'
+fnamemodify('abc.fb2.tar.gz', ':e:e:e:e') 'fb2.tar.gz'
+fnamemodify('abc.fb2.tar.gz', ':e:e:r' ) 'tar'
+fnamemodify('abc def', ':S' ) '''abc def'''
+fnamemodify('abc" "def', ':S' ) '''abc" "def'''
+fnamemodify('abc"%"def', ':S' ) '''abc"%"def'''
+fnamemodify('abc'' ''def', ':S' ) '''abc''\'''' ''\''''def'''
+fnamemodify('abc''%''def', ':S' ) '''abc''\''''%''\''''def'''
+fnamemodify("abc\ndef", ':S' ) '''abc^@def'''
+fnamemodify("abc\ndef", ':S' ) '''abc\^@def'''
+vim: ts=8
diff --git a/src/version.c b/src/version.c
index 5a03359fec..6e0e05bb7e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -216,7 +216,7 @@ static int included_patches[] = {
//194,
193,
192,
- //191,
+ 191,
//190,
//189,
//188,