[SCM] Vim packaging branch, maint/lenny, updated. debian/7.1.314-3-51-g209709e

James Vega jamessan at debian.org
Sun Oct 12 06:29:05 UTC 2008


The following commit has been merged in the maint/lenny branch:
commit f0f00e974139aaf3de3b8acba98991bac2b65958
Author: James Vega <jamessan at debian.org>
Date:   Thu Oct 9 00:26:56 2008 -0400

    [7.2a.013] shellescape() does not escape "%" and "#" characters
    
    Patch 7.2a.013
    Problem:    shellescape() does not escape "%" and "#" characters.
    Solution:   Add find_cmdline_var() and use it when the second argument to
    	    shellescape() is non-zero.
    
    Conflicts:
    
    	runtime/doc/eval.txt
    	src/eval.c
    	src/version.c
    
    Signed-off-by: James Vega <jamessan at debian.org>

diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index aade0fd..8209be6 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1760,7 +1760,8 @@ setreg( {n}, {v}[, {opt}])	Number	set register to value and type
 settabwinvar( {tabnr}, {winnr}, {varname}, {val})    set {varname} in window
 					{winnr} in tab page {tabnr} to {val}
 setwinvar( {nr}, {varname}, {val})	set {varname} in window {nr} to {val}
-shellescape( {string})		String	escape {string} for use as shell
+shellescape( {string} [, {special}])
+				String	escape {string} for use as shell
 					command argument
 simplify( {filename})		String	simplify filename as much as possible
 sort( {list} [, {func}])	List	sort {list}, using {func} to compare
@@ -4663,19 +4664,23 @@ setwinvar({nr}, {varname}, {val})			*setwinvar()*
 			:call setwinvar(1, "&list", 0)
 			:call setwinvar(2, "myvar", "foobar")
 
-shellescape({string})					*shellescape()*
+shellescape({string} [, {special}])			*shellescape()*
 		Escape {string} for use as shell command argument.
 		On MS-Windows and MS-DOS, when 'shellslash' is not set, it
-		will enclose {string} double quotes and double all double
+		will enclose {string} in double quotes and double all double
 		quotes within {string}.
 		For other systems, it will enclose {string} in single quotes
 		and replace all "'" with "'\''".
-		Example: >
-			:echo shellescape('c:\program files\vim')
-<		results in:
-			"c:\program files\vim" ~
-		Example usage: >
-			:call system("chmod +x -- " . shellescape(expand("%")))
+		When the {special} argument is present and it's a non-zero
+		Number or a non-empty String (|non-zero-arg|), then special
+		items such as "%", "#" and "<cword>" will be preceded by a
+		backslash.  This backslash will be removed again by the |:!|
+		command.
+		Example of use with a |:!| command: >
+		    :exe '!dir ' . shellescape(expand('<cfile>'), 1)
+<		This results in a directory listing for the file under the
+		cursor.  Example of use with |system()|: >
+		    :call system("chmod +w -- " . shellescape(expand("%")))
 
 
 simplify({filename})					*simplify()*
@@ -5015,13 +5020,14 @@ system({expr} [, {input}])				*system()* *E677*
 		passed as stdin to the command.  The string is written as-is,
 		you need to take care of using the correct line separators
 		yourself.  Pipes are not used.
-		Note: newlines in {expr} may cause the command to fail.  The
-		characters in 'shellquote' and 'shellxquote' may also cause
-		trouble.
+		Note: Use |shellescape()| to escape special characters in a
+		command argument.  Newlines in {expr} may cause the command to
+		fail.  The characters in 'shellquote' and 'shellxquote' may
+		also cause trouble.
 		This is not to be used for interactive commands.
-		The result is a String.  Example: >
 
-			:let files = system("ls")
+		The result is a String.  Example: >
+		    :let files = system("ls " .  shellescape(expand('%:h')))
 
 <		To make the result more system-independent, the shell output
 		is filtered to replace <CR> with <NL> for Macintosh, and
@@ -5226,11 +5232,13 @@ visualmode([expr])						*visualmode()*
 		Visual mode that was used.
 		If Visual mode is active, use |mode()| to get the Visual mode
 		(e.g., in a |:vmap|).
-
-		If an expression is supplied that results in a non-zero number
-		or a non-empty string, then the Visual mode will be cleared
-		and the old value is returned.  Note that " " and "0" are also
-		non-empty strings, thus cause the mode to be cleared.
+							*non-zero-arg*
+		If [expr] is supplied and it evaluates to a non-zero Number or
+		a non-empty String, then the Visual mode will be cleared and
+		the old value is returned.  Note that " " and "0" are also
+		non-empty strings, thus cause the mode to be cleared.  A List
+		or Dictionary is not a Number or String, thus does not cause
+		the mode to be cleared.
 
 							*winbufnr()*
 winbufnr({nr})	The result is a Number, which is the number of the buffer
@@ -6402,8 +6410,10 @@ This would call the function "my_func_whizz(parameter)".
 
 			Be careful to correctly escape special characters in
 			file names.  The |fnameescape()| function can be used
-			for this.  Example: >
+			for Vim commands, |shellescape()| for |:!| commands.
+			Examples: >
 		:execute "e " . fnameescape(filename)
+		:execute "!ls " . shellescape(expand('%:h'), 1)
 <
 			Note: The executed string may be any command-line, but
 			you cannot start or end a "while", "for" or "if"
diff --git a/src/eval.c b/src/eval.c
index 1ad9cec..72cc3ec 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -456,6 +456,7 @@ static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
 static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
 static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict));
 static void emsg_funcname __ARGS((char *ermsg, char_u *name));
+static int non_zero_arg __ARGS((typval_T *argvars));
 
 static void f_add __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_append __ARGS((typval_T *argvars, typval_T *rettv));
@@ -7235,7 +7236,7 @@ static struct fst
     {"setreg",		2, 3, f_setreg},
     {"settabwinvar",	4, 4, f_settabwinvar},
     {"setwinvar",	3, 3, f_setwinvar},
-    {"shellescape",	1, 1, f_shellescape},
+    {"shellescape",	1, 2, f_shellescape},
     {"simplify",	1, 1, f_simplify},
     {"sort",		1, 2, f_sort},
     {"soundfold",	1, 1, f_soundfold},
@@ -7708,6 +7709,20 @@ emsg_funcname(ermsg, name)
 	vim_free(p);
 }
 
+/*
+ * Return TRUE for a non-zero Number and a non-empty String.
+ */
+    static int
+non_zero_arg(argvars)
+    typval_T	*argvars;
+{
+    return ((argvars[0].v_type == VAR_NUMBER
+		&& argvars[0].vval.v_number != 0)
+	    || (argvars[0].v_type == VAR_STRING
+		&& argvars[0].vval.v_string != NULL
+		&& *argvars[0].vval.v_string != NUL));
+}
+
 /*********************************************
  * Implementation of the built-in functions
  */
@@ -15038,7 +15053,8 @@ f_shellescape(argvars, rettv)
     typval_T	*argvars;
     typval_T	*rettv;
 {
-    rettv->vval.v_string = vim_strsave_shellescape(get_tv_string(&argvars[0]));
+    rettv->vval.v_string = vim_strsave_shellescape(
+		       get_tv_string(&argvars[0]), non_zero_arg(&argvars[1]));
     rettv->v_type = VAR_STRING;
 }
 
@@ -16548,10 +16564,7 @@ f_visualmode(argvars, rettv)
     rettv->vval.v_string = vim_strsave(str);
 
     /* A non-zero number or non-empty string argument: reset mode. */
-    if ((argvars[0].v_type == VAR_NUMBER
-		&& argvars[0].vval.v_number != 0)
-	    || (argvars[0].v_type == VAR_STRING
-		&& *get_tv_string(&argvars[0]) != NUL))
+    if (non_zero_arg(&argvars[0]))
 	curbuf->b_visual_mode_eval = NUL;
 #else
     rettv->vval.v_number = 0; /* return anything, it won't work anyway */
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 71a7b1b..04c7a4c 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -9325,6 +9325,58 @@ ex_tag_cmd(eap, name)
 }
 
 /*
+ * Check "str" for starting with a special cmdline variable.
+ * If found return one of the SPEC_ values and set "*usedlen" to the length of
+ * the variable.  Otherwise return -1 and "*usedlen" is unchanged.
+ */
+    int
+find_cmdline_var(src, usedlen)
+    char_u	*src;
+    int		*usedlen;
+{
+    int		len;
+    int		i;
+    static char *(spec_str[]) = {
+		    "%",
+#define SPEC_PERC   0
+		    "#",
+#define SPEC_HASH   1
+		    "<cword>",		/* cursor word */
+#define SPEC_CWORD  2
+		    "<cWORD>",		/* cursor WORD */
+#define SPEC_CCWORD 3
+		    "<cfile>",		/* cursor path name */
+#define SPEC_CFILE  4
+		    "<sfile>",		/* ":so" file name */
+#define SPEC_SFILE  5
+#ifdef FEAT_AUTOCMD
+		    "<afile>",		/* autocommand file name */
+# define SPEC_AFILE 6
+		    "<abuf>",		/* autocommand buffer number */
+# define SPEC_ABUF  7
+		    "<amatch>",		/* autocommand match name */
+# define SPEC_AMATCH 8
+#endif
+#ifdef FEAT_CLIENTSERVER
+		    "<client>"
+# define SPEC_CLIENT 9
+#endif
+    };
+#define SPEC_COUNT  (sizeof(spec_str) / sizeof(char *))
+
+    for (i = 0; i < SPEC_COUNT; ++i)
+    {
+	len = (int)STRLEN(spec_str[i]);
+	if (STRNCMP(src, spec_str[i], len) == 0)
+	{
+	    *usedlen = len;
+	    return i;
+	}
+    }
+    return -1;
+}
+
+/*
  * Evaluate cmdline variables.
  *
  * change '%'	    to curbuf->b_ffname
@@ -9364,34 +9416,6 @@ eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped)
 #ifdef FEAT_MODIFY_FNAME
     int		skip_mod = FALSE;
 #endif
-    static char *(spec_str[]) =
-	{
-		    "%",
-#define SPEC_PERC   0
-		    "#",
-#define SPEC_HASH   1
-		    "<cword>",		/* cursor word */
-#define SPEC_CWORD  2
-		    "<cWORD>",		/* cursor WORD */
-#define SPEC_CCWORD 3
-		    "<cfile>",		/* cursor path name */
-#define SPEC_CFILE  4
-		    "<sfile>",		/* ":so" file name */
-#define SPEC_SFILE  5
-#ifdef FEAT_AUTOCMD
-		    "<afile>",		/* autocommand file name */
-# define SPEC_AFILE 6
-		    "<abuf>",		/* autocommand buffer number */
-# define SPEC_ABUF  7
-		    "<amatch>",		/* autocommand match name */
-# define SPEC_AMATCH 8
-#endif
-#ifdef FEAT_CLIENTSERVER
-		    "<client>"
-# define SPEC_CLIENT 9
-#endif
-		};
-#define SPEC_COUNT  (sizeof(spec_str) / sizeof(char *))
 
 #if defined(FEAT_AUTOCMD) || defined(FEAT_CLIENTSERVER)
     char_u	strbuf[30];
@@ -9404,13 +9428,8 @@ eval_vars(src, srcstart, usedlen, lnump, errormsg, escaped)
     /*
      * Check if there is something to do.
      */
-    for (spec_idx = 0; spec_idx < SPEC_COUNT; ++spec_idx)
-    {
-	*usedlen = (int)STRLEN(spec_str[spec_idx]);
-	if (STRNCMP(src, spec_str[spec_idx], *usedlen) == 0)
-	    break;
-    }
-    if (spec_idx == SPEC_COUNT)	    /* no match */
+    spec_idx = find_cmdline_var(src, usedlen);
+    if (spec_idx < 0)	/* no match */
     {
 	*usedlen = 1;
 	return NULL;
diff --git a/src/misc2.c b/src/misc2.c
index 6a562d8..fee0a4d 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1265,16 +1265,19 @@ vim_strsave_escaped_ext(string, esc_chars, cc, bsl)
  * Escape "string" for use as a shell argument with system().
  * This uses single quotes, except when we know we need to use double qoutes
  * (MS-DOS and MS-Windows without 'shellslash' set).
+ * Also replace "%", "#" and things like "<cfile>" when "do_special" is TRUE.
  * Returns the result in allocated memory, NULL if we have run out.
  */
     char_u *
-vim_strsave_shellescape(string)
+vim_strsave_shellescape(string, do_special)
     char_u	*string;
+    int		do_special;
 {
     unsigned	length;
     char_u	*p;
     char_u	*d;
     char_u	*escaped_string;
+    int		l;
 
     /* First count the number of extra bytes required. */
     length = (unsigned)STRLEN(string) + 3;  /* two quotes and a trailing NUL */
@@ -1290,6 +1293,11 @@ vim_strsave_shellescape(string)
 # endif
 	if (*p == '\'')
 	    length += 3;		/* ' => '\'' */
+	if (do_special && find_cmdline_var(p, &l) >= 0)
+	{
+	    ++length;			/* insert backslash */
+	    p += l - 1;
+	}
     }
 
     /* Allocate memory for the result and fill it. */
@@ -1330,6 +1338,12 @@ vim_strsave_shellescape(string)
 		++p;
 		continue;
 	    }
+	    if (do_special && find_cmdline_var(p, &l) >= 0)
+	    {
+		*d++ = '\\';		/* insert backslash */
+		while (--l >= 0)	/* copy the var */
+		    *d++ = *p++;
+	    }
 
 	    MB_COPY_CHAR(p, d);
 	}
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index 5835db0..e267acf 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -46,6 +46,7 @@ int vim_mkdir_emsg __ARGS((char_u *name, int prot));
 FILE *open_exfile __ARGS((char_u *fname, int forceit, char *mode));
 void update_topline_cursor __ARGS((void));
 void exec_normal_cmd __ARGS((char_u *cmd, int remap, int silent));
+int find_cmdline_var __ARGS((char_u *src, int *usedlen));
 char_u *eval_vars __ARGS((char_u *src, char_u *srcstart, int *usedlen, linenr_T *lnump, char_u **errormsg, int *escaped));
 char_u *expand_sfile __ARGS((char_u *arg));
 int put_eol __ARGS((FILE *fd));
diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro
index 195b895..8574835 100644
--- a/src/proto/misc2.pro
+++ b/src/proto/misc2.pro
@@ -29,7 +29,7 @@ char_u *vim_strsave __ARGS((char_u *string));
 char_u *vim_strnsave __ARGS((char_u *string, int len));
 char_u *vim_strsave_escaped __ARGS((char_u *string, char_u *esc_chars));
 char_u *vim_strsave_escaped_ext __ARGS((char_u *string, char_u *esc_chars, int cc, int bsl));
-char_u *vim_strsave_shellescape __ARGS((char_u *string));
+char_u *vim_strsave_shellescape __ARGS((char_u *string, int do_special));
 char_u *vim_strsave_up __ARGS((char_u *string));
 char_u *vim_strnsave_up __ARGS((char_u *string, int len));
 void vim_strup __ARGS((char_u *p));

-- 
Vim packaging



More information about the pkg-vim-maintainers mailing list