A couple of problems were detected when the Unix shell is used to expand
file names containing characters such as a single quote.  This applies
to completion on the command line and glob().

I made a patch that defines a function to echo each file name
separately.  Inspired by a patch that Dasn made, but staying on the safe
side.

The patch for ex_docmd.c changes detecting the end of the file name when
doing command line completion.  This specifically fixes a file name
containing "&".

Please try it out and let me know if there are any new problems.



*** ../vim-7.1.197/src/os_unix.c        Thu Jan  3 18:55:21 2008
--- src/os_unix.c       Fri Jan  4 12:59:41 2008
***************
*** 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,5154 ----
        else if (STRCMP(p_sh + len - 3, "zsh") == 0)
            shell_style = STYLE_PRINT;
      }
+     else if (strstr((char *)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 ****
--- 5207,5220 ----
            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
--- 5260,5266 ----
      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);
--- 5292,5298 ----
      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)
--- 5363,5369 ----
      }
      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;
--- 5386,5392 ----
        }
      }
      /* 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)
--- 5465,5472 ----
      {
        (*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)
*** ../vim-7.1.197/src/ex_docmd.c       Wed Jan  2 21:07:32 2008
--- src/ex_docmd.c      Thu Jan  3 22:04:21 2008
***************
*** 3338,3349 ****
                }
                in_quote = !in_quote;
            }
  #ifdef SPACE_IN_FILENAME
!           else if (!vim_isfilec_or_wc(c)
!                                        && (!(ea.argt & NOSPC) || usefilter))
! #else
!           else if (!vim_isfilec_or_wc(c))
  #endif
            {
                while (*p != NUL)
                {
--- 3338,3350 ----
                }
                in_quote = !in_quote;
            }
+           /* An argument can contain just about everything, except
+            * characters that end the command and white space. */
+           else if (c == '|' || c == '\n' || c == '"' || (vim_iswhite(c)
  #ifdef SPACE_IN_FILENAME
!                                        && (!(ea.argt & NOSPC) || usefilter)
  #endif
+                   ))
            {
                while (*p != NUL)
                {


-- 
CUSTOMER:     You're not fooling anyone y'know.  Look, isn't there something
              you can do?
DEAD PERSON:  I feel happy... I feel happy.
    [whop]
CUSTOMER:     Ah, thanks very much.
MORTICIAN:    Not at all.  See you on Thursday.
CUSTOMER:     Right.
                                  The Quest for the Holy Grail (Monty Python)

 /// Bram Moolenaar -- [EMAIL PROTECTED] -- 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    ///

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui