From: Bram Moolenaar Date: Mon, 3 Oct 2016 19:37:41 +0000 (+0200) Subject: patch 8.0.0022 X-Git-Tag: v8.0.0022 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec68a99464055029c01082762517e97245ddae0c;p=vim patch 8.0.0022 Problem: If a channel in NL mode is missing the NL at the end the remaining characters are dropped. Solution: When the channel is closed use the remaining text. (Ozaki Kiichi) --- diff --git a/src/channel.c b/src/channel.c index 13fb65302..d4ec60b75 100644 --- a/src/channel.c +++ b/src/channel.c @@ -2355,8 +2355,9 @@ may_invoke_callback(channel_T *channel, int part) typval_T *listtv = NULL; typval_T argv[CH_JSON_MAX_ARGS]; int seq_nr = -1; - ch_mode_T ch_mode = channel->ch_part[part].ch_mode; - cbq_T *cbhead = &channel->ch_part[part].ch_cb_head; + chanpart_T *ch_part = &channel->ch_part[part]; + ch_mode_T ch_mode = ch_part->ch_mode; + cbq_T *cbhead = &ch_part->ch_cb_head; cbq_T *cbitem; char_u *callback = NULL; partial_T *partial = NULL; @@ -2376,10 +2377,10 @@ may_invoke_callback(channel_T *channel, int part) callback = cbitem->cq_callback; partial = cbitem->cq_partial; } - else if (channel->ch_part[part].ch_callback != NULL) + else if (ch_part->ch_callback != NULL) { - callback = channel->ch_part[part].ch_callback; - partial = channel->ch_part[part].ch_partial; + callback = ch_part->ch_callback; + partial = ch_part->ch_partial; } else { @@ -2387,11 +2388,11 @@ may_invoke_callback(channel_T *channel, int part) partial = channel->ch_partial; } - buffer = channel->ch_part[part].ch_bufref.br_buf; - if (buffer != NULL && !bufref_valid(&channel->ch_part[part].ch_bufref)) + buffer = ch_part->ch_bufref.br_buf; + if (buffer != NULL && !bufref_valid(&ch_part->ch_bufref)) { /* buffer was wiped out */ - channel->ch_part[part].ch_bufref.br_buf = NULL; + ch_part->ch_bufref.br_buf = NULL; buffer = NULL; } @@ -2452,7 +2453,7 @@ may_invoke_callback(channel_T *channel, int part) if (ch_mode == MODE_NL) { - char_u *nl; + char_u *nl = NULL; char_u *buf; readq_T *node; @@ -2465,10 +2466,25 @@ may_invoke_callback(channel_T *channel, int part) if (nl != NULL) break; if (channel_collapse(channel, part, TRUE) == FAIL) + { + if (ch_part->ch_fd == INVALID_FD && node->rq_buflen > 0) + break; return FALSE; /* incomplete message */ + } } buf = node->rq_buffer; + if (nl == NULL) + { + /* Flush remaining message that is missing a NL. */ + buf = vim_realloc(buf, node->rq_buflen + 1); + if (buf == NULL) + return FALSE; + node->rq_buffer = buf; + nl = buf + node->rq_buflen++; + *nl = NUL; + } + /* Convert NUL to NL, the internal representation. */ for (p = buf; p < nl && p < buf + node->rq_buflen; ++p) if (*p == NUL) diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index eb75a0b1d..0756dd51c 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -1484,6 +1484,27 @@ func Test_raw_passes_nul() bwipe! endfunc +func MyLineCountCb(ch, msg) + let g:linecount += 1 +endfunc + +func Test_read_nonl_line() + if !has('job') + return + endif + + let g:linecount = 0 + if has('win32') + " workaround: 'shellescape' does improper escaping double quotes + let arg = 'import sys;sys.stdout.write(\"1\n2\n3\")' + else + let arg = 'import sys;sys.stdout.write("1\n2\n3")' + endif + call job_start([s:python, '-c', arg], {'callback': 'MyLineCountCb'}) + call WaitFor('3 <= g:linecount') + call assert_equal(3, g:linecount) +endfunc + function Ch_test_close_lambda(port) let handle = ch_open('localhost:' . a:port, s:chopt) if ch_status(handle) == "fail" diff --git a/src/version.c b/src/version.c index dc8e9cf35..4fd2982a5 100644 --- a/src/version.c +++ b/src/version.c @@ -764,6 +764,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 22, /**/ 21, /**/