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.

Raspunde prin e-mail lui