To: vim-dev@vim.org Subject: Patch 7.0.111 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 7.0.111 Problem: The gzip plugin can't handle filenames with single quotes. Solution: Add and use the shellescape() function. (partly by Alexey Froloff) Files: runtime/autoload/gzip.vim, runtime/doc/eval.txt, src/eval.c, src/mbyte.c, src/misc2.c, src/proto/misc2.pro *** ../vim-7.0.110/runtime/autoload/gzip.vim Tue Aug 8 19:55:06 2006 --- runtime/autoload/gzip.vim Tue Oct 3 14:39:29 2006 *************** *** 1,6 **** " Vim autoload file for editing compressed files. " Maintainer: Bram Moolenaar ! " Last Change: 2006 Jul 19 " These functions are used by the gzip plugin. --- 1,6 ---- " Vim autoload file for editing compressed files. " Maintainer: Bram Moolenaar ! " Last Change: 2006 Oct 03 " These functions are used by the gzip plugin. *************** *** 68,76 **** let tmp = tempname() let tmpe = tmp . "." . expand(":e") " write the just read lines to a temp file "'[,']w tmp.gz" ! execute "silent '[,']w " . tmpe " uncompress the temp file: call system("gzip -dn tmp.gz") ! call system(a:cmd . " " . tmpe) if !filereadable(tmp) " uncompress didn't work! Keep the compressed file then. echoerr "Error: Could not read uncompressed file" --- 68,76 ---- let tmp = tempname() let tmpe = tmp . "." . expand(":e") " write the just read lines to a temp file "'[,']w tmp.gz" ! execute "silent '[,']w " . escape(tmpe, ' ') " uncompress the temp file: call system("gzip -dn tmp.gz") ! call system(a:cmd . " " . s:escape(tmpe)) if !filereadable(tmp) " uncompress didn't work! Keep the compressed file then. echoerr "Error: Could not read uncompressed file" *************** *** 127,135 **** let nmt = s:tempname(nm) if rename(nm, nmt) == 0 if exists("b:gzip_comp_arg") ! call system(a:cmd . " " . b:gzip_comp_arg . " '" . nmt . "'") else ! call system(a:cmd . " '" . nmt . "'") endif call rename(nmt . "." . expand(":e"), nm) endif --- 127,135 ---- let nmt = s:tempname(nm) if rename(nm, nmt) == 0 if exists("b:gzip_comp_arg") ! call system(a:cmd . " " . b:gzip_comp_arg . " " . s:escape(nmt)) else ! call system(a:cmd . " " . s:escape(nmt)) endif call rename(nmt . "." . expand(":e"), nm) endif *************** *** 154,163 **** if rename(nm, nmte) == 0 if &patchmode != "" && getfsize(nm . &patchmode) == -1 " Create patchmode file by creating the decompressed file new ! call system(a:cmd . " -c " . nmte . " > " . nmt) call rename(nmte, nm . &patchmode) else ! call system(a:cmd . " " . nmte) endif call rename(nmt, nm) endif --- 154,163 ---- if rename(nm, nmte) == 0 if &patchmode != "" && getfsize(nm . &patchmode) == -1 " Create patchmode file by creating the decompressed file new ! call system(a:cmd . " -c " . s:escape(nmte) . " > " . s:escape(nmt)) call rename(nmte, nm . &patchmode) else ! call system(a:cmd . " " . s:escape(nmte)) endif call rename(nmt, nm) endif *************** *** 173,178 **** --- 173,186 ---- return fn endif return fnamemodify(a:name, ":p:h") . "/X~=@l9q5" + endfun + + fun s:escape(name) + " shellescape() was added by patch 7.0.111 + if v:version > 700 || (v:version == 700 && has('patch111')) + return shellescape(a:name) + endif + return "'" . a:name . "'" endfun " vim: set sw=2 : *** ../vim-7.0.110/runtime/doc/eval.txt Sun May 7 17:08:32 2006 --- runtime/doc/eval.txt Fri Sep 22 19:43:18 2006 *************** *** 1,4 **** ! *eval.txt* For Vim version 7.0. Last change: 2006 May 06 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *eval.txt* For Vim version 7.0. Last change: 2006 Sep 22 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 1709,1714 **** --- 1715,1722 ---- 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 + command argument simplify( {filename}) String simplify filename as much as possible sort( {list} [, {func}]) List sort {list}, using {func} to compare soundfold( {word}) String sound-fold {word} *************** *** 4434,4439 **** --- 4457,4477 ---- :call setwinvar(1, "&list", 0) :call setwinvar(2, "myvar", "foobar") + shellescape({string}) *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 + 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("%"))) + + simplify({filename}) *simplify()* Simplify the file name as much as possible without changing the meaning. Shortcuts (on MS-Windows) or symbolic links (on *** ../vim-7.0.110/src/eval.c Sat Sep 9 12:05:39 2006 --- src/eval.c Thu Sep 14 17:44:41 2006 *************** *** 622,627 **** --- 622,628 ---- static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); static void f_settabwinvar __ARGS((typval_T *argvars, typval_T *rettv)); static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_shellescape __ARGS((typval_T *argvars, typval_T *rettv)); static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); *************** *** 7146,7151 **** --- 7147,7153 ---- {"setreg", 2, 3, f_setreg}, {"settabwinvar", 4, 4, f_settabwinvar}, {"setwinvar", 3, 3, f_setwinvar}, + {"shellescape", 1, 1, f_shellescape}, {"simplify", 1, 1, f_simplify}, {"sort", 1, 2, f_sort}, {"soundfold", 1, 1, f_soundfold}, *************** *** 14602,14607 **** --- 14604,14621 ---- } #endif } + } + + /* + * "shellescape({string})" function + */ + static void + f_shellescape(argvars, rettv) + typval_T *argvars; + typval_T *rettv; + { + rettv->vval.v_string = vim_strsave_shellescape(get_tv_string(&argvars[0])); + rettv->v_type = VAR_STRING; } /* *** ../vim-7.0.110/src/misc2.c Thu May 4 23:50:56 2006 --- src/misc2.c Tue Sep 26 23:13:57 2006 *************** *** 1229,1234 **** --- 1229,1322 ---- return escaped_string; } + #if defined(FEAT_EVAL) || defined(PROTO) + /* + * 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). + * Returns the result in allocated memory, NULL if we have run out. + */ + char_u * + vim_strsave_shellescape(string) + char_u *string; + { + unsigned length; + char_u *p; + char_u *d; + char_u *escaped_string; + + /* First count the number of extra bytes required. */ + length = STRLEN(string) + 3; /* two quotes and the trailing NUL */ + for (p = string; *p != NUL; mb_ptr_adv(p)) + { + # if defined(WIN32) || defined(WIN16) || defined(DOS) + if (!p_ssl) + { + if (*p == '"') + ++length; /* " -> "" */ + } + else + # endif + if (*p == '\'') + length += 3; /* ' => '\'' */ + } + + /* Allocate memory for the result and fill it. */ + escaped_string = alloc(length); + if (escaped_string != NULL) + { + d = escaped_string; + + /* add opening quote */ + # if defined(WIN32) || defined(WIN16) || defined(DOS) + if (!p_ssl) + *d++ = '"'; + else + # endif + *d++ = '\''; + + for (p = string; *p != NUL; ) + { + # if defined(WIN32) || defined(WIN16) || defined(DOS) + if (!p_ssl) + { + if (*p == '"') + { + *d++ = '"'; + *d++ = '"'; + ++p; + continue; + } + } + else + # endif + if (*p == '\'') + { + *d++='\''; + *d++='\\'; + *d++='\''; + *d++='\''; + ++p; + continue; + } + + MB_COPY_CHAR(p, d); + } + + /* add terminating quote and finish with a NUL */ + # if defined(WIN32) || defined(WIN16) || defined(DOS) + if (!p_ssl) + *d++ = '"'; + else + # endif + *d++ = '\''; + *d = NUL; + } + + return escaped_string; + } + #endif + /* * Like vim_strsave(), but make all characters uppercase. * This uses ASCII lower-to-upper case translation, language independent. *** ../vim-7.0.110/src/proto/misc2.pro Fri Mar 24 23:42:55 2006 --- src/proto/misc2.pro Thu Sep 14 18:28:43 2006 *************** *** 29,34 **** --- 29,35 ---- extern char_u *vim_strnsave __ARGS((char_u *string, int len)); extern char_u *vim_strsave_escaped __ARGS((char_u *string, char_u *esc_chars)); extern char_u *vim_strsave_escaped_ext __ARGS((char_u *string, char_u *esc_chars, int cc, int bsl)); + extern char_u *vim_strsave_shellescape __ARGS((char_u *string)); extern char_u *vim_strsave_up __ARGS((char_u *string)); extern char_u *vim_strnsave_up __ARGS((char_u *string, int len)); extern void vim_strup __ARGS((char_u *p)); *** ../vim-7.0.110/src/version.c Tue Sep 26 13:49:41 2006 --- src/version.c Tue Oct 3 14:36:40 2006 *************** *** 668,669 **** --- 668,671 ---- { /* Add new patch number below this line */ + /**/ + 111, /**/ -- The only way the average employee can speak to an executive is by taking a second job as a golf caddie. (Scott Adams - The Dilbert principle) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ download, build and distribute -- http://www.A-A-P.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///