Patch 7.4.1336
Problem: Channel NL mode is not supported yet.
Solution: Add NL mode support to channels.
Files: src/channel.c, src/netbeans.c, src/structs.h, src/os_unix.d,
src/os_win32.c, src/proto/channel.pro, src/proto/os_unix.pro,
src/proto/os_win32.pro, src/testdir/test_channel.vim,
src/testdir/test_channel_pipe.py
*** ../vim-7.4.1335/src/channel.c 2016-02-16 15:06:54.653635399 +0100
--- src/channel.c 2016-02-16 19:21:46.979016087 +0100
***************
*** 669,680 ****
}
/*
! * Set the json mode of channel "channel" to "ch_mode".
*/
void
! channel_set_json_mode(channel_T *channel, ch_mode_T ch_mode)
{
! channel->ch_mode = ch_mode;
}
/*
--- 669,680 ----
}
/*
! * Set the mode of channel "channel" to "mode".
*/
void
! channel_set_mode(channel_T *channel, ch_mode_T mode)
{
! channel->ch_mode = mode;
}
/*
***************
*** 1057,1063 ****
/*
* Invoke a callback for channel "channel" if needed.
! * Return OK when a message was handled, there might be another one.
*/
static int
may_invoke_callback(channel_T *channel)
--- 1057,1064 ----
/*
* Invoke a callback for channel "channel" if needed.
! * TODO: add "which" argument, read stderr.
! * Return TRUE when a message was handled, there might be another one.
*/
static int
may_invoke_callback(channel_T *channel)
***************
*** 1074,1080 ****
/* this channel is handled elsewhere (netbeans) */
return FALSE;
! if (ch_mode != MODE_RAW)
{
/* Get any json message in the queue. */
if (channel_get_json(channel, -1, &listtv) == FAIL)
--- 1075,1081 ----
/* this channel is handled elsewhere (netbeans) */
return FALSE;
! if (ch_mode == MODE_JSON || ch_mode == MODE_JS)
{
/* Get any json message in the queue. */
if (channel_get_json(channel, -1, &listtv) == FAIL)
***************
*** 1113,1130 ****
}
else if (channel_peek(channel) == NULL)
{
! /* nothing to read on raw channel */
return FALSE;
}
else
{
! /* If there is no callback, don't do anything. */
if (channel->ch_callback == NULL)
return FALSE;
- /* For a raw channel we don't know where the message ends, just get
- * everything. */
- msg = channel_get_all(channel);
argv[1].v_type = VAR_STRING;
argv[1].vval.v_string = msg;
}
--- 1114,1164 ----
}
else if (channel_peek(channel) == NULL)
{
! /* nothing to read on RAW or NL channel */
return FALSE;
}
else
{
! /* If there is no callback drop the message. */
if (channel->ch_callback == NULL)
+ {
+ while ((msg = channel_get(channel)) != NULL)
+ vim_free(msg);
return FALSE;
+ }
+
+ if (ch_mode == MODE_NL)
+ {
+ char_u *nl;
+ char_u *buf;
+
+ /* See if we have a message ending in NL in the first buffer. If
+ * not try to concatenate the first and the second buffer. */
+ while (TRUE)
+ {
+ buf = channel_peek(channel);
+ nl = vim_strchr(buf, NL);
+ if (nl != NULL)
+ break;
+ if (channel_collapse(channel) == FAIL)
+ return FALSE; /* incomplete message */
+ }
+ if (nl[1] == NUL)
+ /* get the whole buffer */
+ msg = channel_get(channel);
+ else
+ {
+ /* Copy the message into allocated memory and remove it from
+ * the buffer. */
+ msg = vim_strnsave(buf, (int)(nl - buf));
+ mch_memmove(buf, nl + 1, STRLEN(nl + 1) + 1);
+ }
+ }
+ else
+ /* For a raw channel we don't know where the message ends, just
+ * get everything we have. */
+ msg = channel_get_all(channel);
argv[1].v_type = VAR_STRING;
argv[1].vval.v_string = msg;
}
***************
*** 1276,1287 ****
return FAIL; /* out of memory */
}
! /* TODO: don't strip CR when channel is in raw mode */
! p = node->rq_buffer;
! for (i = 0; i < len; ++i)
! if (buf[i] != CAR || i + 1 >= len || buf[i + 1] != NL)
! *p++ = buf[i];
! *p = NUL;
/* append node to the tail of the queue */
node->rq_next = NULL;
--- 1310,1329 ----
return FAIL; /* out of memory */
}
! if (channel->ch_mode == MODE_NL)
! {
! /* Drop any CR before a NL. */
! p = node->rq_buffer;
! for (i = 0; i < len; ++i)
! if (buf[i] != CAR || i + 1 >= len || buf[i + 1] != NL)
! *p++ = buf[i];
! *p = NUL;
! }
! else
! {
! mch_memmove(node->rq_buffer, buf, len);
! node->rq_buffer[len] = NUL;
! }
/* append node to the tail of the queue */
node->rq_next = NULL;
***************
*** 1570,1590 ****
}
/*
! * Read from raw channel "channel". Blocks until there is something to read
or
! * the timeout expires.
* Returns what was read in allocated memory.
* Returns NULL in case of error or timeout.
*/
char_u *
channel_read_block(channel_T *channel)
{
! ch_log(channel, "Reading raw\n");
! if (channel_peek(channel) == NULL)
! {
! sock_T fd = get_read_fd(channel);
- /* TODO: read both out and err if they are different */
- ch_log(channel, "No readahead\n");
/* Wait for up to the channel timeout. */
if (fd == CHAN_FD_INVALID
|| channel_wait(channel, fd, channel->ch_timeout) == FAIL)
--- 1612,1644 ----
}
/*
! * Read from RAW or NL channel "channel". Blocks until there is something to
! * read or the timeout expires.
! * TODO: add "which" argument and read from stderr.
* Returns what was read in allocated memory.
* Returns NULL in case of error or timeout.
*/
char_u *
channel_read_block(channel_T *channel)
{
! char_u *buf;
! char_u *msg;
! ch_mode_T mode = channel->ch_mode;
! sock_T fd = get_read_fd(channel);
! char_u *nl;
!
! ch_logsn(channel, "Blocking %s read, timeout: %d msec\n",
! mode == MODE_RAW ? "RAW" : "NL", channel->ch_timeout);
!
! while (TRUE)
! {
! buf = channel_peek(channel);
! if (buf != NULL && (mode == MODE_RAW
! || (mode == MODE_NL && vim_strchr(buf, NL) != NULL)))
! break;
! if (buf != NULL && channel_collapse(channel) == OK)
! continue;
/* Wait for up to the channel timeout. */
if (fd == CHAN_FD_INVALID
|| channel_wait(channel, fd, channel->ch_timeout) == FAIL)
***************
*** 1592,1600 ****
channel_read(channel, -1, "channel_read_block");
}
! /* TODO: only get the first message */
! ch_log(channel, "Returning readahead\n");
! return channel_get_all(channel);
}
/*
--- 1646,1675 ----
channel_read(channel, -1, "channel_read_block");
}
! if (mode == MODE_RAW)
! {
! msg = channel_get_all(channel);
! }
! else
! {
! nl = vim_strchr(buf, NL);
! if (nl[1] == NUL)
! {
! /* get the whole buffer */
! msg = channel_get(channel);
! *nl = NUL;
! }
! else
! {
! /* Copy the message into allocated memory and remove it from the
! * buffer. */
! msg = vim_strnsave(buf, (int)(nl - buf));
! mch_memmove(buf, nl + 1, STRLEN(nl + 1) + 1);
! }
! }
! if (log_fd != NULL)
! ch_logn(channel, "Returning %d bytes\n", (int)STRLEN(msg));
! return msg;
}
/*
*** ../vim-7.4.1335/src/structs.h 2016-02-15 21:56:42.725119689 +0100
--- src/structs.h 2016-02-16 18:26:49.949294135 +0100
***************
*** 1372,1377 ****
--- 1372,1385 ----
int ch_refcount; /* reference count */
};
+ /*
+ * Options for job commands.
+ */
+ typedef struct
+ {
+ ch_mode_T jo_mode;
+ } jobopt_T;
+
/* structure used for explicit stack while garbage collecting hash tables */
typedef struct ht_stack_S
*** ../vim-7.4.1335/src/os_win32.c 2016-02-16 16:39:47.923933523 +0100
--- src/os_win32.c 2016-02-16 18:43:28.618921026 +0100
***************
*** 5034,5040 ****
#if defined(FEAT_JOB) || defined(PROTO)
void
! mch_start_job(char *cmd, job_T *job)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
--- 5034,5040 ----
#if defined(FEAT_JOB) || defined(PROTO)
void
! mch_start_job(char *cmd, job_T *job, jobopt_T *options)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
***************
*** 5121,5126 ****
--- 5121,5127 ----
job->jv_channel = channel;
channel_set_pipes(channel, (sock_T)ifd[1], (sock_T)ofd[0],
(sock_T)efd[0]);
channel_set_job(channel, job);
+ channel_set_mode(channel, options->jo_mode);
# ifdef FEAT_GUI
channel_gui_register(channel);
*** ../vim-7.4.1335/src/proto/channel.pro 2016-02-15 21:56:42.721119732
+0100
--- src/proto/channel.pro 2016-02-16 17:53:44.893894420 +0100
***************
*** 7,13 ****
channel_T *channel_open(char *hostname, int port_in, int waittime, void
(*close_cb)(void));
void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err);
void channel_set_job(channel_T *channel, job_T *job);
! void channel_set_json_mode(channel_T *channel, ch_mode_T ch_mode);
void channel_set_timeout(channel_T *channel, int timeout);
void channel_set_callback(channel_T *channel, char_u *callback);
void channel_set_req_callback(channel_T *channel, char_u *callback, int id);
--- 7,13 ----
channel_T *channel_open(char *hostname, int port_in, int waittime, void
(*close_cb)(void));
void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err);
void channel_set_job(channel_T *channel, job_T *job);
! void channel_set_mode(channel_T *channel, ch_mode_T ch_mode);
void channel_set_timeout(channel_T *channel, int timeout);
void channel_set_callback(channel_T *channel, char_u *callback);
void channel_set_req_callback(channel_T *channel, char_u *callback, int id);
*** ../vim-7.4.1335/src/proto/os_unix.pro 2016-02-12 19:30:20.353885756
+0100
--- src/proto/os_unix.pro 2016-02-16 18:43:41.154790744 +0100
***************
*** 57,63 ****
void mch_new_shellsize(void);
int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc);
int mch_call_shell(char_u *cmd, int options);
! void mch_start_job(char **argv, job_T *job);
char *mch_job_status(job_T *job);
int mch_stop_job(job_T *job, char_u *how);
void mch_clear_job(job_T *job);
--- 57,63 ----
void mch_new_shellsize(void);
int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc);
int mch_call_shell(char_u *cmd, int options);
! void mch_start_job(char **argv, job_T *job, jobopt_T *options);
char *mch_job_status(job_T *job);
int mch_stop_job(job_T *job, char_u *how);
void mch_clear_job(job_T *job);
*** ../vim-7.4.1335/src/proto/os_win32.pro 2016-02-12 19:30:20.353885756
+0100
--- src/proto/os_win32.pro 2016-02-16 18:43:35.862845741 +0100
***************
*** 40,46 ****
void mch_new_shellsize(void);
void mch_set_winsize_now(void);
int mch_call_shell(char_u *cmd, int options);
! void mch_start_job(char *cmd, job_T *job);
char *mch_job_status(job_T *job);
int mch_stop_job(job_T *job, char_u *how);
void mch_clear_job(job_T *job);
--- 40,46 ----
void mch_new_shellsize(void);
void mch_set_winsize_now(void);
int mch_call_shell(char_u *cmd, int options);
! void mch_start_job(char *cmd, job_T *job, jobopt_T *options);
char *mch_job_status(job_T *job);
int mch_stop_job(job_T *job, char_u *how);
void mch_clear_job(job_T *job);
*** ../vim-7.4.1335/src/testdir/test_channel.vim 2016-02-16
14:07:36.190482636 +0100
--- src/testdir/test_channel.vim 2016-02-16 19:23:23.150013903 +0100
***************
*** 284,290 ****
endif
endfunc
! func Test_pipe()
if !has('job')
return
endif
--- 284,313 ----
endif
endfunc
! func Test_raw_pipe()
! if !has('job')
! return
! endif
! let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
! call assert_equal("run", job_status(job))
! try
! let handle = job_getchannel(job)
! call ch_sendraw(handle, "echo something\n", 0)
! let msg = ch_readraw(handle)
! call assert_equal("something\n", substitute(msg, "\r", "", 'g'))
!
! call ch_sendraw(handle, "double this\n", 0)
! let msg = ch_readraw(handle)
! call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g'))
!
! let reply = ch_sendraw(handle, "quit\n")
! call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g'))
! finally
! call job_stop(job)
! endtry
! endfunc
!
! func Test_nl_pipe()
if !has('job')
return
endif
***************
*** 293,301 ****
try
let handle = job_getchannel(job)
call ch_sendraw(handle, "echo something\n", 0)
! call assert_equal("something\n", ch_readraw(handle))
let reply = ch_sendraw(handle, "quit\n")
! call assert_equal("Goodbye!\n", reply)
finally
call job_stop(job)
endtry
--- 316,329 ----
try
let handle = job_getchannel(job)
call ch_sendraw(handle, "echo something\n", 0)
! call assert_equal("something", ch_readraw(handle))
!
! call ch_sendraw(handle, "double this\n", 0)
! call assert_equal("this", ch_readraw(handle))
! call assert_equal("AND this", ch_readraw(handle))
!
let reply = ch_sendraw(handle, "quit\n")
! call assert_equal("Goodbye!", reply)
finally
call job_stop(job)
endtry
*** ../vim-7.4.1335/src/testdir/test_channel_pipe.py 2016-02-13
17:04:08.426819018 +0100
--- src/testdir/test_channel_pipe.py 2016-02-16 19:02:36.058998429 +0100
***************
*** 21,24 ****
--- 21,27 ----
if typed.startswith("echo"):
print(typed[5:-1])
sys.stdout.flush()
+ if typed.startswith("double"):
+ print(typed[7:-1] + "\nAND " + typed[7:-1])
+ sys.stdout.flush()
*** ../vim-7.4.1335/src/version.c 2016-02-16 16:39:47.923933523 +0100
--- src/version.c 2016-02-16 18:16:14.023894517 +0100
***************
*** 749,750 ****
--- 749,752 ----
{ /* Add new patch number below this line */
+ /**/
+ 1336,
/**/
--
He was not in the least bit scared to be mashed into a pulp
Or to have his eyes gouged out and his elbows broken;
To have his kneecaps split and his body burned away
And his limbs all hacked and mangled, brave Sir Robin.
"Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.