| To: vim-dev@vim.org |
| Subject: Patch 7.1.223 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=ISO-8859-1 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 7.1.223 |
| Problem: glob() doesn't work properly when 'shell' is "sh" or "bash" and |
| the expanded name contains spaces, '~', single quotes and other |
| special characters. (Adri Verhoef, Charles Campbell) |
| Solution: For Posix shells define a vimglob() function to list the matches |
| instead of using "echo" directly. |
| Files: src/os_unix.c |
| |
| |
| |
| |
| |
| *** 4946,4951 **** |
| --- 4946,4954 ---- |
| char_u *p; |
| int dir; |
| #ifdef __EMX__ |
| + /* |
| + * This is the OS/2 implementation. |
| + */ |
| # define EXPL_ALLOC_INC 16 |
| char_u **expl_files; |
| size_t files_alloced, files_free; |
| |
| *** 5056,5075 **** |
| return OK; |
| |
| #else /* __EMX__ */ |
| ! |
| int j; |
| char_u *tempname; |
| char_u *command; |
| FILE *fd; |
| char_u *buffer; |
| ! #define STYLE_ECHO 0 /* use "echo" to expand */ |
| ! #define STYLE_GLOB 1 /* use "glob" to expand, for csh */ |
| ! #define STYLE_PRINT 2 /* use "print -N" to expand, for zsh */ |
| ! #define STYLE_BT 3 /* `cmd` expansion, execute the pattern directly */ |
| int shell_style = STYLE_ECHO; |
| int check_spaces; |
| static int did_find_nul = FALSE; |
| int ampersent = FALSE; |
| |
| *num_file = 0; /* default: no files found */ |
| *file = NULL; |
| --- 5059,5084 ---- |
| return OK; |
| |
| #else /* __EMX__ */ |
| ! /* |
| ! * This is the non-OS/2 implementation (really Unix). |
| ! */ |
| int j; |
| char_u *tempname; |
| char_u *command; |
| FILE *fd; |
| char_u *buffer; |
| ! #define STYLE_ECHO 0 /* use "echo", the default */ |
| ! #define STYLE_GLOB 1 /* use "glob", for csh */ |
| ! #define STYLE_VIMGLOB 2 /* use "vimglob", for Posix sh */ |
| ! #define STYLE_PRINT 3 /* use "print -N", for zsh */ |
| ! #define STYLE_BT 4 /* `cmd` expansion, execute the pattern |
| ! * directly */ |
| int shell_style = STYLE_ECHO; |
| int check_spaces; |
| static int did_find_nul = FALSE; |
| int ampersent = FALSE; |
| + /* vimglob() function to define for Posix shell */ |
| + static char *sh_vimglob_func = "vimglob() { while [ $# -ge 1 ]; do echo -n \"$1\"; echo; shift; done }; vimglob >"; |
| |
| *num_file = 0; /* default: no files found */ |
| *file = NULL; |
| |
| *** 5107,5115 **** |
| |
| /* |
| * Let the shell expand the patterns and write the result into the temp |
| ! * file. if expanding `cmd` execute it directly. |
| ! * If we use csh, glob will work better than echo. |
| ! * If we use zsh, print -N will work better than glob. |
| */ |
| if (num_pat == 1 && *pat[0] == '`' |
| && (len = STRLEN(pat[0])) > 2 |
| --- 5116,5132 ---- |
| |
| /* |
| * Let the shell expand the patterns and write the result into the temp |
| ! * file. |
| ! * STYLE_BT: NL separated |
| ! * If expanding `cmd` execute it directly. |
| ! * STYLE_GLOB: NUL separated |
| ! * If we use *csh, "glob" will work better than "echo". |
| ! * STYLE_PRINT: NL or NUL separated |
| ! * If we use *zsh, "print -N" will work better than "glob". |
| ! * STYLE_VIMGLOB: NL separated |
| ! * If we use *sh*, we define "vimglob()". |
| ! * STYLE_ECHO: space separated. |
| ! * A shell we don't know, stay safe and use "echo". |
| */ |
| if (num_pat == 1 && *pat[0] == '`' |
| && (len = STRLEN(pat[0])) > 2 |
| |
| *** 5122,5130 **** |
| else if (STRCMP(p_sh + len - 3, "zsh") == 0) |
| shell_style = STYLE_PRINT; |
| } |
| ! |
| ! /* "unset nonomatch; print -N >" plus two is 29 */ |
| len = STRLEN(tempname) + 29; |
| for (i = 0; i < num_pat; ++i) |
| { |
| /* Count the length of the patterns in the same way as they are put in |
| --- 5139,5155 ---- |
| else if (STRCMP(p_sh + len - 3, "zsh") == 0) |
| shell_style = STYLE_PRINT; |
| } |
| ! if (shell_style == STYLE_ECHO && strstr((char *)gettail(p_sh), |
| ! "sh") != NULL) |
| ! shell_style = STYLE_VIMGLOB; |
| ! |
| ! /* Compute the length of the command. We need 2 extra bytes: for the |
| ! * optional '&' and for the NUL. |
| ! * Worst case: "unset nonomatch; print -N >" plus two is 29 */ |
| len = STRLEN(tempname) + 29; |
| + if (shell_style == STYLE_VIMGLOB) |
| + len += STRLEN(sh_vimglob_func); |
| + |
| for (i = 0; i < num_pat; ++i) |
| { |
| /* Count the length of the patterns in the same way as they are put in |
| |
| *** 5183,5192 **** |
| --- 5208,5221 ---- |
| STRCAT(command, "glob >"); |
| else if (shell_style == STYLE_PRINT) |
| STRCAT(command, "print -N >"); |
| + else if (shell_style == STYLE_VIMGLOB) |
| + STRCAT(command, sh_vimglob_func); |
| else |
| STRCAT(command, "echo >"); |
| } |
| + |
| STRCAT(command, tempname); |
| + |
| if (shell_style != STYLE_BT) |
| for (i = 0; i < num_pat; ++i) |
| { |
| |
| *** 5232,5239 **** |
| if (flags & EW_SILENT) |
| show_shell_mess = FALSE; |
| if (ampersent) |
| ! STRCAT(command, "&"); /* put the '&' back after the |
| ! redirection */ |
| |
| /* |
| * Using zsh -G: If a pattern has no matches, it is just deleted from |
| --- 5261,5267 ---- |
| if (flags & EW_SILENT) |
| show_shell_mess = FALSE; |
| if (ampersent) |
| ! STRCAT(command, "&"); /* put the '&' after the redirection */ |
| |
| /* |
| * Using zsh -G: If a pattern has no matches, it is just deleted from |
| |
| *** 5265,5271 **** |
| show_shell_mess = TRUE; |
| vim_free(command); |
| |
| ! if (i) /* mch_call_shell() failed */ |
| { |
| mch_remove(tempname); |
| vim_free(tempname); |
| --- 5293,5299 ---- |
| show_shell_mess = TRUE; |
| vim_free(command); |
| |
| ! if (i != 0) /* mch_call_shell() failed */ |
| { |
| mch_remove(tempname); |
| vim_free(tempname); |
| |
| *** 5336,5342 **** |
| } |
| vim_free(tempname); |
| |
| ! #if defined(__CYGWIN__) || defined(__CYGWIN32__) |
| /* Translate <CR><NL> into <NL>. Caution, buffer may contain NUL. */ |
| p = buffer; |
| for (i = 0; i < len; ++i) |
| --- 5364,5370 ---- |
| } |
| vim_free(tempname); |
| |
| ! # if defined(__CYGWIN__) || defined(__CYGWIN32__) |
| /* Translate <CR><NL> into <NL>. Caution, buffer may contain NUL. */ |
| p = buffer; |
| for (i = 0; i < len; ++i) |
| |
| *** 5359,5365 **** |
| } |
| } |
| /* file names are separated with NL */ |
| ! else if (shell_style == STYLE_BT) |
| { |
| buffer[len] = NUL; /* make sure the buffer ends in NUL */ |
| p = buffer; |
| --- 5387,5393 ---- |
| } |
| } |
| /* file names are separated with NL */ |
| ! else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) |
| { |
| buffer[len] = NUL; /* make sure the buffer ends in NUL */ |
| p = buffer; |
| |
| *** 5438,5444 **** |
| { |
| (*file)[i] = p; |
| /* Space or NL separates */ |
| ! if (shell_style == STYLE_ECHO || shell_style == STYLE_BT) |
| { |
| while (!(shell_style == STYLE_ECHO && *p == ' ') |
| && *p != '\n' && *p != NUL) |
| --- 5466,5473 ---- |
| { |
| (*file)[i] = p; |
| /* Space or NL separates */ |
| ! if (shell_style == STYLE_ECHO || shell_style == STYLE_BT |
| ! || shell_style == STYLE_VIMGLOB) |
| { |
| while (!(shell_style == STYLE_ECHO && *p == ' ') |
| && *p != '\n' && *p != NUL) |
| |
| |
| |
| *** 668,669 **** |
| --- 668,671 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 223, |
| /**/ |
| |
| -- |
| User: I'm having problems with my text editor. |
| Help desk: Which editor are you using? |
| User: I don't know, but it's version VI (pronounced: 6). |
| Help desk: Oh, then you should upgrade to version VIM (pronounced: 994). |
| |
| /// 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 /// |