]> granicus.if.org Git - vim/commitdiff
patch 7.4.2189 v7.4.2189
authorBram Moolenaar <Bram@vim.org>
Tue, 9 Aug 2016 20:14:05 +0000 (22:14 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 9 Aug 2016 20:14:05 +0000 (22:14 +0200)
Problem:    Cannot detect encoding in a fifo.
Solution:   Extend the stdin way of detecting encoding to fifo.  Add a test
            for detecting encoding on stdin and fifo. (Ken Takata)

src/Makefile
src/buffer.c
src/fileio.c
src/testdir/Make_all.mak
src/testdir/test_startup_utf8.vim [new file with mode: 0644]
src/version.c
src/vim.h

index be2f31b92c3562e6f1ee74341edfa4c8c91c3f1a..e15df1bc54f1a84d0d2784cb81d09ae5b27ebe9f 100644 (file)
@@ -2114,6 +2114,7 @@ test_arglist \
        test_signs \
        test_sort \
        test_startup \
+       test_startup_utf8 \
        test_stat \
        test_statusline \
        test_syn_attr \
index 60fb67a23b41ca7998327f16a9dbed457344fa27..2a09a6308b0eaeea43f747a656c2cf63bef7c64f 100644 (file)
@@ -70,6 +70,64 @@ static char *e_auabort = N_("E855: Autocommands caused command to abort");
 /* Number of times free_buffer() was called. */
 static int     buf_free_count = 0;
 
+/* Read data from buffer for retrying. */
+    static int
+read_buffer(
+    int                read_stdin,         /* read file from stdin, otherwise fifo */
+    exarg_T    *eap,               /* for forced 'ff' and 'fenc' or NULL */
+    int                flags)              /* extra flags for readfile() */
+{
+    int                retval = OK;
+    linenr_T   line_count;
+
+    /*
+     * Read from the buffer which the text is already filled in and append at
+     * the end.  This makes it possible to retry when 'fileformat' or
+     * 'fileencoding' was guessed wrong.
+     */
+    line_count = curbuf->b_ml.ml_line_count;
+    retval = readfile(
+           read_stdin ? NULL : curbuf->b_ffname,
+           read_stdin ? NULL : curbuf->b_fname,
+           (linenr_T)line_count, (linenr_T)0, (linenr_T)MAXLNUM, eap,
+           flags | READ_BUFFER);
+    if (retval == OK)
+    {
+       /* Delete the binary lines. */
+       while (--line_count >= 0)
+           ml_delete((linenr_T)1, FALSE);
+    }
+    else
+    {
+       /* Delete the converted lines. */
+       while (curbuf->b_ml.ml_line_count > line_count)
+           ml_delete(line_count, FALSE);
+    }
+    /* Put the cursor on the first line. */
+    curwin->w_cursor.lnum = 1;
+    curwin->w_cursor.col = 0;
+
+    if (read_stdin)
+    {
+       /* Set or reset 'modified' before executing autocommands, so that
+        * it can be changed there. */
+       if (!readonlymode && !bufempty())
+           changed();
+       else if (retval != FAIL)
+           unchanged(curbuf, FALSE);
+
+#ifdef FEAT_AUTOCMD
+# ifdef FEAT_EVAL
+       apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
+                                                       curbuf, &retval);
+# else
+       apply_autocmds(EVENT_STDINREADPOST, NULL, NULL, FALSE, curbuf);
+# endif
+#endif
+    }
+    return retval;
+}
+
 /*
  * Open current buffer, that is: open the memfile and read the file into
  * memory.
@@ -88,6 +146,7 @@ open_buffer(
 #ifdef FEAT_SYN_HL
     long       old_tw = curbuf->b_p_tw;
 #endif
+    int                read_fifo = FALSE;
 
     /*
      * The 'readonly' flag is only set when BF_NEVERLOADED is being reset.
@@ -143,17 +202,42 @@ open_buffer(
        )
     {
        int old_msg_silent = msg_silent;
-
+#ifdef UNIX
+       int save_bin = curbuf->b_p_bin;
+       int perm;
+#endif
 #ifdef FEAT_NETBEANS_INTG
        int oldFire = netbeansFireChanges;
 
        netbeansFireChanges = 0;
+#endif
+#ifdef UNIX
+       perm = mch_getperm(curbuf->b_ffname);
+       if (perm >= 0 && (0
+# ifdef S_ISFIFO
+                     || S_ISFIFO(perm)
+# endif
+# ifdef S_ISSOCK
+                     || S_ISSOCK(perm)
+# endif
+                   ))
+               read_fifo = TRUE;
+       if (read_fifo)
+           curbuf->b_p_bin = TRUE;
 #endif
        if (shortmess(SHM_FILEINFO))
            msg_silent = 1;
        retval = readfile(curbuf->b_ffname, curbuf->b_fname,
                  (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap,
-                 flags | READ_NEW);
+                 flags | READ_NEW | (read_fifo ? READ_FIFO : 0));
+#ifdef UNIX
+       if (read_fifo)
+       {
+           curbuf->b_p_bin = save_bin;
+           if (retval == OK)
+               retval = read_buffer(FALSE, eap, flags);
+       }
+#endif
        msg_silent = old_msg_silent;
 #ifdef FEAT_NETBEANS_INTG
        netbeansFireChanges = oldFire;
@@ -164,8 +248,7 @@ open_buffer(
     }
     else if (read_stdin)
     {
-       int             save_bin = curbuf->b_p_bin;
-       linenr_T        line_count;
+       int     save_bin = curbuf->b_p_bin;
 
        /*
         * First read the text in binary mode into the buffer.
@@ -179,42 +262,7 @@ open_buffer(
                  flags | (READ_NEW + READ_STDIN));
        curbuf->b_p_bin = save_bin;
        if (retval == OK)
-       {
-           line_count = curbuf->b_ml.ml_line_count;
-           retval = readfile(NULL, NULL, (linenr_T)line_count,
-                           (linenr_T)0, (linenr_T)MAXLNUM, eap,
-                           flags | READ_BUFFER);
-           if (retval == OK)
-           {
-               /* Delete the binary lines. */
-               while (--line_count >= 0)
-                   ml_delete((linenr_T)1, FALSE);
-           }
-           else
-           {
-               /* Delete the converted lines. */
-               while (curbuf->b_ml.ml_line_count > line_count)
-                   ml_delete(line_count, FALSE);
-           }
-           /* Put the cursor on the first line. */
-           curwin->w_cursor.lnum = 1;
-           curwin->w_cursor.col = 0;
-
-           /* Set or reset 'modified' before executing autocommands, so that
-            * it can be changed there. */
-           if (!readonlymode && !bufempty())
-               changed();
-           else if (retval != FAIL)
-               unchanged(curbuf, FALSE);
-#ifdef FEAT_AUTOCMD
-# ifdef FEAT_EVAL
-           apply_autocmds_retval(EVENT_STDINREADPOST, NULL, NULL, FALSE,
-                                                       curbuf, &retval);
-# else
-           apply_autocmds(EVENT_STDINREADPOST, NULL, NULL, FALSE, curbuf);
-# endif
-#endif
-       }
+           retval = read_buffer(TRUE, eap, flags);
     }
 
     /* if first time loading this buffer, init b_chartab[] */
@@ -243,7 +291,7 @@ open_buffer(
 #endif
        )
        changed();
-    else if (retval != FAIL && !read_stdin)
+    else if (retval != FAIL && !read_stdin && !read_fifo)
        unchanged(curbuf, FALSE);
     save_file_ff(curbuf);              /* keep this fileformat */
 
index 042bbec6e108d11324e7ebb7381d16b72669e655..3c3d54835d9b8636d2627f377f88c3be5e723cf1 100644 (file)
@@ -212,6 +212,7 @@ filemess(
  *             stdin)
  * READ_DUMMY  read into a dummy buffer (to check if file contents changed)
  * READ_KEEP_UNDO  don't clear undo info or read it from a file
+ * READ_FIFO   read from fifo/socket instead of a file
  *
  * return FAIL for failure, OK otherwise
  */
@@ -231,6 +232,7 @@ readfile(
     int                filtering = (flags & READ_FILTER);
     int                read_stdin = (flags & READ_STDIN);
     int                read_buffer = (flags & READ_BUFFER);
+    int                read_fifo = (flags & READ_FIFO);
     int                set_options = newfile || read_buffer
                                           || (eap != NULL && eap->read_edit);
     linenr_T   read_buf_lnum = 1;      /* next line to read from curbuf */
@@ -431,7 +433,7 @@ readfile(
        }
     }
 
-    if (!read_stdin && !read_buffer)
+    if (!read_stdin && !read_buffer && !read_fifo)
     {
 #ifdef UNIX
        /*
@@ -489,7 +491,7 @@ readfile(
     if (check_readonly && !readonlymode)
        curbuf->b_p_ro = FALSE;
 
-    if (newfile && !read_stdin && !read_buffer)
+    if (newfile && !read_stdin && !read_buffer && !read_fifo)
     {
        /* Remember time of file. */
        if (mch_stat((char *)fname, &st) >= 0)
@@ -1101,6 +1103,7 @@ retry:
         * and we can't do it internally or with iconv().
         */
        if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
+                                                   && !read_fifo
 #  ifdef USE_ICONV
                                                    && iconv_fd == (iconv_t)-1
 #  endif
@@ -1149,7 +1152,7 @@ retry:
     /* Set "can_retry" when it's possible to rewind the file and try with
      * another "fenc" value.  It's FALSE when no other "fenc" to try, reading
      * stdin or fixed at a specific encoding. */
-    can_retry = (*fenc != NUL && !read_stdin && !keep_dest_enc);
+    can_retry = (*fenc != NUL && !read_stdin && !read_fifo && !keep_dest_enc);
 #endif
 
     if (!skip_read)
@@ -1166,6 +1169,7 @@ retry:
                                  && curbuf->b_ffname != NULL
                                  && curbuf->b_p_udf
                                  && !filtering
+                                 && !read_fifo
                                  && !read_stdin
                                  && !read_buffer);
        if (read_undo_file)
@@ -2666,7 +2670,7 @@ failed:
 #endif
 
 #ifdef FEAT_AUTOCMD
-    if (!read_stdin && !read_buffer)
+    if (!read_stdin && !read_fifo && (!read_buffer || sfname != NULL))
     {
        int m = msg_scroll;
        int n = msg_scrolled;
@@ -2685,7 +2689,7 @@ failed:
        if (filtering)
            apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
                                                          FALSE, curbuf, eap);
-       else if (newfile)
+       else if (newfile || (read_buffer && sfname != NULL))
        {
            apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
                                                          FALSE, curbuf, eap);
index 0ed91d76f444c6853f46ce6ef2dfa76c6a2dd5b2..0a5ee927b02e0dfb633842c9cbcf2c9dd2215f3d 100644 (file)
@@ -185,6 +185,7 @@ NEW_TESTS = test_arglist.res \
            test_ruby.res \
            test_signs.res \
            test_startup.res \
+           test_startup_utf8.res \
            test_stat.res \
            test_syntax.res \
            test_textobjects.res \
diff --git a/src/testdir/test_startup_utf8.vim b/src/testdir/test_startup_utf8.vim
new file mode 100644 (file)
index 0000000..d179a4c
--- /dev/null
@@ -0,0 +1,64 @@
+" Tests for startup using utf-8.
+if !has('multi_byte')
+  finish
+endif
+
+source shared.vim
+
+func Test_read_stdin_utf8()
+  let linesin = ['テスト', '€ÀÈÌÒÙ']
+  call writefile(linesin, 'Xtestin')
+  let before = [
+       \ 'set enc=utf-8',
+       \ 'set fencs=cp932,utf-8',
+       \ ]
+  let after = [
+       \ 'write ++enc=utf-8 Xtestout',
+       \ 'quit!',
+       \ ]
+  if has('win32')
+    let pipecmd = 'type Xtestin | '
+  else
+    let pipecmd = 'cat Xtestin | '
+  endif
+  if RunVimPiped(before, after, '-', pipecmd)
+    let lines = readfile('Xtestout')
+    call assert_equal(linesin, lines)
+  else
+    call assert_equal('', 'RunVimPiped failed.')
+  endif
+  call delete('Xtestout')
+  call delete('Xtestin')
+endfunc
+
+func Test_read_fifo_utf8()
+  if !has('unix')
+    return
+  endif
+  " Using bash/zsh's process substitution.
+  if executable('bash')
+    set shell=bash
+  elseif executable('zsh')
+    set shell=zsh
+  else
+    return
+  endif
+  let linesin = ['テスト', '€ÀÈÌÒÙ']
+  call writefile(linesin, 'Xtestin')
+  let before = [
+       \ 'set enc=utf-8',
+       \ 'set fencs=cp932,utf-8',
+       \ ]
+  let after = [
+       \ 'write ++enc=utf-8 Xtestout',
+       \ 'quit!',
+       \ ]
+  if RunVim(before, after, '<(cat Xtestin)')
+    let lines = readfile('Xtestout')
+    call assert_equal(linesin, lines)
+  else
+    call assert_equal('', 'RunVim failed.')
+  endif
+  call delete('Xtestout')
+  call delete('Xtestin')
+endfunc
index 4d4c16e27136606b1b56ef1a4f92d60c54a854e8..72ec3820a143bb2816365fe49a2a81164d396b5b 100644 (file)
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2189,
 /**/
     2188,
 /**/
index 96cfc6ccadba129804cf3fb9b64bd496a291ab6a..8b51b09efc2d7c8b9a9ca7a6ed4ba64518d2ebb0 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -980,7 +980,8 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
 #define READ_STDIN     0x04    /* read from stdin */
 #define READ_BUFFER    0x08    /* read from curbuf (converting stdin) */
 #define READ_DUMMY     0x10    /* reading into a dummy buffer */
-#define READ_KEEP_UNDO 0x20    /* keep undo info*/
+#define READ_KEEP_UNDO 0x20    /* keep undo info */
+#define READ_FIFO      0x40    /* read from fifo or socket */
 
 /* Values for change_indent() */
 #define INDENT_SET     1       /* set indent */