forked from aniani/vim
patch 7.4.2189
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)
This commit is contained in:
@@ -2114,6 +2114,7 @@ test_arglist \
|
|||||||
test_signs \
|
test_signs \
|
||||||
test_sort \
|
test_sort \
|
||||||
test_startup \
|
test_startup \
|
||||||
|
test_startup_utf8 \
|
||||||
test_stat \
|
test_stat \
|
||||||
test_statusline \
|
test_statusline \
|
||||||
test_syn_attr \
|
test_syn_attr \
|
||||||
|
130
src/buffer.c
130
src/buffer.c
@@ -70,6 +70,64 @@ static char *e_auabort = N_("E855: Autocommands caused command to abort");
|
|||||||
/* Number of times free_buffer() was called. */
|
/* Number of times free_buffer() was called. */
|
||||||
static int buf_free_count = 0;
|
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
|
* Open current buffer, that is: open the memfile and read the file into
|
||||||
* memory.
|
* memory.
|
||||||
@@ -88,6 +146,7 @@ open_buffer(
|
|||||||
#ifdef FEAT_SYN_HL
|
#ifdef FEAT_SYN_HL
|
||||||
long old_tw = curbuf->b_p_tw;
|
long old_tw = curbuf->b_p_tw;
|
||||||
#endif
|
#endif
|
||||||
|
int read_fifo = FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The 'readonly' flag is only set when BF_NEVERLOADED is being reset.
|
* The 'readonly' flag is only set when BF_NEVERLOADED is being reset.
|
||||||
@@ -143,17 +202,42 @@ open_buffer(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
int old_msg_silent = msg_silent;
|
int old_msg_silent = msg_silent;
|
||||||
|
#ifdef UNIX
|
||||||
|
int save_bin = curbuf->b_p_bin;
|
||||||
|
int perm;
|
||||||
|
#endif
|
||||||
#ifdef FEAT_NETBEANS_INTG
|
#ifdef FEAT_NETBEANS_INTG
|
||||||
int oldFire = netbeansFireChanges;
|
int oldFire = netbeansFireChanges;
|
||||||
|
|
||||||
netbeansFireChanges = 0;
|
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
|
#endif
|
||||||
if (shortmess(SHM_FILEINFO))
|
if (shortmess(SHM_FILEINFO))
|
||||||
msg_silent = 1;
|
msg_silent = 1;
|
||||||
retval = readfile(curbuf->b_ffname, curbuf->b_fname,
|
retval = readfile(curbuf->b_ffname, curbuf->b_fname,
|
||||||
(linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, eap,
|
(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;
|
msg_silent = old_msg_silent;
|
||||||
#ifdef FEAT_NETBEANS_INTG
|
#ifdef FEAT_NETBEANS_INTG
|
||||||
netbeansFireChanges = oldFire;
|
netbeansFireChanges = oldFire;
|
||||||
@@ -164,8 +248,7 @@ open_buffer(
|
|||||||
}
|
}
|
||||||
else if (read_stdin)
|
else if (read_stdin)
|
||||||
{
|
{
|
||||||
int save_bin = curbuf->b_p_bin;
|
int save_bin = curbuf->b_p_bin;
|
||||||
linenr_T line_count;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First read the text in binary mode into the buffer.
|
* First read the text in binary mode into the buffer.
|
||||||
@@ -179,42 +262,7 @@ open_buffer(
|
|||||||
flags | (READ_NEW + READ_STDIN));
|
flags | (READ_NEW + READ_STDIN));
|
||||||
curbuf->b_p_bin = save_bin;
|
curbuf->b_p_bin = save_bin;
|
||||||
if (retval == OK)
|
if (retval == OK)
|
||||||
{
|
retval = read_buffer(TRUE, eap, flags);
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if first time loading this buffer, init b_chartab[] */
|
/* if first time loading this buffer, init b_chartab[] */
|
||||||
@@ -243,7 +291,7 @@ open_buffer(
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
changed();
|
changed();
|
||||||
else if (retval != FAIL && !read_stdin)
|
else if (retval != FAIL && !read_stdin && !read_fifo)
|
||||||
unchanged(curbuf, FALSE);
|
unchanged(curbuf, FALSE);
|
||||||
save_file_ff(curbuf); /* keep this fileformat */
|
save_file_ff(curbuf); /* keep this fileformat */
|
||||||
|
|
||||||
|
14
src/fileio.c
14
src/fileio.c
@@ -212,6 +212,7 @@ filemess(
|
|||||||
* stdin)
|
* stdin)
|
||||||
* READ_DUMMY read into a dummy buffer (to check if file contents changed)
|
* 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_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
|
* return FAIL for failure, OK otherwise
|
||||||
*/
|
*/
|
||||||
@@ -231,6 +232,7 @@ readfile(
|
|||||||
int filtering = (flags & READ_FILTER);
|
int filtering = (flags & READ_FILTER);
|
||||||
int read_stdin = (flags & READ_STDIN);
|
int read_stdin = (flags & READ_STDIN);
|
||||||
int read_buffer = (flags & READ_BUFFER);
|
int read_buffer = (flags & READ_BUFFER);
|
||||||
|
int read_fifo = (flags & READ_FIFO);
|
||||||
int set_options = newfile || read_buffer
|
int set_options = newfile || read_buffer
|
||||||
|| (eap != NULL && eap->read_edit);
|
|| (eap != NULL && eap->read_edit);
|
||||||
linenr_T read_buf_lnum = 1; /* next line to read from curbuf */
|
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
|
#ifdef UNIX
|
||||||
/*
|
/*
|
||||||
@@ -489,7 +491,7 @@ readfile(
|
|||||||
if (check_readonly && !readonlymode)
|
if (check_readonly && !readonlymode)
|
||||||
curbuf->b_p_ro = FALSE;
|
curbuf->b_p_ro = FALSE;
|
||||||
|
|
||||||
if (newfile && !read_stdin && !read_buffer)
|
if (newfile && !read_stdin && !read_buffer && !read_fifo)
|
||||||
{
|
{
|
||||||
/* Remember time of file. */
|
/* Remember time of file. */
|
||||||
if (mch_stat((char *)fname, &st) >= 0)
|
if (mch_stat((char *)fname, &st) >= 0)
|
||||||
@@ -1101,6 +1103,7 @@ retry:
|
|||||||
* and we can't do it internally or with iconv().
|
* and we can't do it internally or with iconv().
|
||||||
*/
|
*/
|
||||||
if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
|
if (fio_flags == 0 && !read_stdin && !read_buffer && *p_ccv != NUL
|
||||||
|
&& !read_fifo
|
||||||
# ifdef USE_ICONV
|
# ifdef USE_ICONV
|
||||||
&& iconv_fd == (iconv_t)-1
|
&& iconv_fd == (iconv_t)-1
|
||||||
# endif
|
# endif
|
||||||
@@ -1149,7 +1152,7 @@ retry:
|
|||||||
/* Set "can_retry" when it's possible to rewind the file and try with
|
/* 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
|
* another "fenc" value. It's FALSE when no other "fenc" to try, reading
|
||||||
* stdin or fixed at a specific encoding. */
|
* 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
|
#endif
|
||||||
|
|
||||||
if (!skip_read)
|
if (!skip_read)
|
||||||
@@ -1166,6 +1169,7 @@ retry:
|
|||||||
&& curbuf->b_ffname != NULL
|
&& curbuf->b_ffname != NULL
|
||||||
&& curbuf->b_p_udf
|
&& curbuf->b_p_udf
|
||||||
&& !filtering
|
&& !filtering
|
||||||
|
&& !read_fifo
|
||||||
&& !read_stdin
|
&& !read_stdin
|
||||||
&& !read_buffer);
|
&& !read_buffer);
|
||||||
if (read_undo_file)
|
if (read_undo_file)
|
||||||
@@ -2666,7 +2670,7 @@ failed:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
if (!read_stdin && !read_buffer)
|
if (!read_stdin && !read_fifo && (!read_buffer || sfname != NULL))
|
||||||
{
|
{
|
||||||
int m = msg_scroll;
|
int m = msg_scroll;
|
||||||
int n = msg_scrolled;
|
int n = msg_scrolled;
|
||||||
@@ -2685,7 +2689,7 @@ failed:
|
|||||||
if (filtering)
|
if (filtering)
|
||||||
apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
|
apply_autocmds_exarg(EVENT_FILTERREADPOST, NULL, sfname,
|
||||||
FALSE, curbuf, eap);
|
FALSE, curbuf, eap);
|
||||||
else if (newfile)
|
else if (newfile || (read_buffer && sfname != NULL))
|
||||||
{
|
{
|
||||||
apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
|
apply_autocmds_exarg(EVENT_BUFREADPOST, NULL, sfname,
|
||||||
FALSE, curbuf, eap);
|
FALSE, curbuf, eap);
|
||||||
|
@@ -185,6 +185,7 @@ NEW_TESTS = test_arglist.res \
|
|||||||
test_ruby.res \
|
test_ruby.res \
|
||||||
test_signs.res \
|
test_signs.res \
|
||||||
test_startup.res \
|
test_startup.res \
|
||||||
|
test_startup_utf8.res \
|
||||||
test_stat.res \
|
test_stat.res \
|
||||||
test_syntax.res \
|
test_syntax.res \
|
||||||
test_textobjects.res \
|
test_textobjects.res \
|
||||||
|
64
src/testdir/test_startup_utf8.vim
Normal file
64
src/testdir/test_startup_utf8.vim
Normal file
@@ -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
|
@@ -763,6 +763,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2189,
|
||||||
/**/
|
/**/
|
||||||
2188,
|
2188,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -980,7 +980,8 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
|
|||||||
#define READ_STDIN 0x04 /* read from stdin */
|
#define READ_STDIN 0x04 /* read from stdin */
|
||||||
#define READ_BUFFER 0x08 /* read from curbuf (converting stdin) */
|
#define READ_BUFFER 0x08 /* read from curbuf (converting stdin) */
|
||||||
#define READ_DUMMY 0x10 /* reading into a dummy buffer */
|
#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() */
|
/* Values for change_indent() */
|
||||||
#define INDENT_SET 1 /* set indent */
|
#define INDENT_SET 1 /* set indent */
|
||||||
|
Reference in New Issue
Block a user