Patch 8.0.0015
Problem:    Can't tell which part of a channel has "buffered" status.
Solution:   Add an optional argument to ch_status().  Let ch_info() also
            return "buffered" for out_status and err_status.
Files:      src/evalfunc.c, src/channel.c, src/proto/channel.pro,
            src/testdir/test_channel.vim, runtime/doc/eval.txt


*** ../vim-8.0.0014/src/evalfunc.c      2016-09-25 21:44:59.441600148 +0200
--- src/evalfunc.c      2016-09-26 22:03:14.961368676 +0200
***************
*** 514,520 ****
      {"ch_sendexpr",   2, 3, f_ch_sendexpr},
      {"ch_sendraw",    2, 3, f_ch_sendraw},
      {"ch_setoptions", 2, 2, f_ch_setoptions},
!     {"ch_status",     1, 1, f_ch_status},
  #endif
      {"changenr",      0, 0, f_changenr},
      {"char2nr",               1, 2, f_char2nr},
--- 514,520 ----
      {"ch_sendexpr",   2, 3, f_ch_sendexpr},
      {"ch_sendraw",    2, 3, f_ch_sendraw},
      {"ch_setoptions", 2, 2, f_ch_setoptions},
!     {"ch_status",     1, 2, f_ch_status},
  #endif
      {"changenr",      0, 0, f_changenr},
      {"char2nr",               1, 2, f_char2nr},
***************
*** 1985,1997 ****
  f_ch_status(typval_T *argvars, typval_T *rettv)
  {
      channel_T *channel;
  
      /* return an empty string by default */
      rettv->v_type = VAR_STRING;
      rettv->vval.v_string = NULL;
  
      channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0);
!     rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel));
  }
  #endif
  
--- 1985,2008 ----
  f_ch_status(typval_T *argvars, typval_T *rettv)
  {
      channel_T *channel;
+     jobopt_T  opt;
+     int               part = -1;
  
      /* return an empty string by default */
      rettv->v_type = VAR_STRING;
      rettv->vval.v_string = NULL;
  
      channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0);
! 
!     if (argvars[1].v_type != VAR_UNKNOWN)
!     {
!       clear_job_options(&opt);
!       if (get_job_options(&argvars[1], &opt, JO_PART) == OK
!                                                    && (opt.jo_set & JO_PART))
!           part = opt.jo_part;
!     }
! 
!     rettv->vval.v_string = vim_strsave((char_u *)channel_status(channel, 
part));
  }
  #endif
  
*** ../vim-8.0.0014/src/channel.c       2016-09-07 23:15:55.000000000 +0200
--- src/channel.c       2016-09-26 22:19:18.270706785 +0200
***************
*** 2590,2612 ****
  
  /*
   * Return a string indicating the status of the channel.
   */
      char *
! channel_status(channel_T *channel)
  {
      int part;
      int has_readahead = FALSE;
  
      if (channel == NULL)
         return "fail";
!     if (channel_is_open(channel))
!        return "open";
!     for (part = PART_SOCK; part <= PART_ERR; ++part)
!       if (channel_has_readahead(channel, part))
!       {
            has_readahead = TRUE;
!           break;
!       }
  
      if (has_readahead)
        return "buffered";
--- 2590,2630 ----
  
  /*
   * Return a string indicating the status of the channel.
+  * If "req_part" is not negative check that part.
   */
      char *
! channel_status(channel_T *channel, int req_part)
  {
      int part;
      int has_readahead = FALSE;
  
      if (channel == NULL)
         return "fail";
!     if (req_part == PART_OUT)
!     {
!       if (channel->CH_OUT_FD != INVALID_FD)
!           return "open";
!       if (channel_has_readahead(channel, PART_OUT))
            has_readahead = TRUE;
!     }
!     else if (req_part == PART_ERR)
!     {
!       if (channel->CH_ERR_FD != INVALID_FD)
!           return "open";
!       if (channel_has_readahead(channel, PART_ERR))
!           has_readahead = TRUE;
!     }
!     else
!     {
!       if (channel_is_open(channel))
!           return "open";
!       for (part = PART_SOCK; part <= PART_ERR; ++part)
!           if (channel_has_readahead(channel, part))
!           {
!               has_readahead = TRUE;
!               break;
!           }
!     }
  
      if (has_readahead)
        return "buffered";
***************
*** 2619,2624 ****
--- 2637,2643 ----
      chanpart_T *chanpart = &channel->ch_part[part];
      char      namebuf[20];  /* longest is "sock_timeout" */
      size_t    tail;
+     char      *status;
      char      *s = "";
  
      vim_strncpy((char_u *)namebuf, (char_u *)name, 4);
***************
*** 2626,2633 ****
      tail = STRLEN(namebuf);
  
      STRCPY(namebuf + tail, "status");
!     dict_add_nr_str(dict, namebuf, 0,
!               (char_u *)(chanpart->ch_fd == INVALID_FD ? "closed" : "open"));
  
      STRCPY(namebuf + tail, "mode");
      switch (chanpart->ch_mode)
--- 2645,2657 ----
      tail = STRLEN(namebuf);
  
      STRCPY(namebuf + tail, "status");
!     if (chanpart->ch_fd != INVALID_FD)
!       status = "open";
!     else if (channel_has_readahead(channel, part))
!       status = "buffered";
!     else
!       status = "closed";
!     dict_add_nr_str(dict, namebuf, 0, (char_u *)status);
  
      STRCPY(namebuf + tail, "mode");
      switch (chanpart->ch_mode)
***************
*** 2660,2666 ****
  channel_info(channel_T *channel, dict_T *dict)
  {
      dict_add_nr_str(dict, "id", channel->ch_id, NULL);
!     dict_add_nr_str(dict, "status", 0, (char_u *)channel_status(channel));
  
      if (channel->ch_hostname != NULL)
      {
--- 2684,2690 ----
  channel_info(channel_T *channel, dict_T *dict)
  {
      dict_add_nr_str(dict, "id", channel->ch_id, NULL);
!     dict_add_nr_str(dict, "status", 0, (char_u *)channel_status(channel, -1));
  
      if (channel->ch_hostname != NULL)
      {
***************
*** 4244,4249 ****
--- 4268,4275 ----
                val = get_tv_string(item);
                if (STRCMP(val, "err") == 0)
                    opt->jo_part = PART_ERR;
+               else if (STRCMP(val, "out") == 0)
+                   opt->jo_part = PART_OUT;
                else
                {
                    EMSG2(_(e_invarg2), val);
*** ../vim-8.0.0014/src/proto/channel.pro       2016-09-12 13:04:24.000000000 
+0200
--- src/proto/channel.pro       2016-09-26 22:14:54.376537165 +0200
***************
*** 24,30 ****
  int channel_collapse(channel_T *channel, int part, int want_nl);
  int channel_can_write_to(channel_T *channel);
  int channel_is_open(channel_T *channel);
! char *channel_status(channel_T *channel);
  void channel_info(channel_T *channel, dict_T *dict);
  void channel_close(channel_T *channel, int invoke_close_cb);
  void channel_close_in(channel_T *channel);
--- 24,30 ----
  int channel_collapse(channel_T *channel, int part, int want_nl);
  int channel_can_write_to(channel_T *channel);
  int channel_is_open(channel_T *channel);
! char *channel_status(channel_T *channel, int req_part);
  void channel_info(channel_T *channel, dict_T *dict);
  void channel_close(channel_T *channel, int invoke_close_cb);
  void channel_close_in(channel_T *channel);
*** ../vim-8.0.0014/src/testdir/test_channel.vim        2016-09-07 
23:23:56.000000000 +0200
--- src/testdir/test_channel.vim        2016-09-26 22:34:36.352321622 +0200
***************
*** 434,439 ****
--- 434,456 ----
    let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
    call assert_equal(v:t_job, type(job))
    call assert_equal("run", job_status(job))
+ 
+   call assert_equal("open", ch_status(job))
+   call assert_equal("open", ch_status(job), {"part": "out"})
+   call assert_equal("open", ch_status(job), {"part": "err"})
+   call assert_fails('call ch_status(job, {"in_mode": "raw"})', 'E475:')
+   call assert_fails('call ch_status(job, {"part": "in"})', 'E475:')
+ 
+   let dict = ch_info(job)
+   call assert_true(dict.id != 0)
+   call assert_equal('open', dict.status)
+   call assert_equal('open', dict.out_status)
+   call assert_equal('RAW', dict.out_mode)
+   call assert_equal('pipe', dict.out_io)
+   call assert_equal('open', dict.err_status)
+   call assert_equal('RAW', dict.err_mode)
+   call assert_equal('pipe', dict.err_io)
+ 
    try
      " For a change use the job where a channel is expected.
      call ch_sendraw(job, "echo something\n")
*** ../vim-8.0.0014/runtime/doc/eval.txt        2016-09-12 12:45:25.000000000 
+0200
--- runtime/doc/eval.txt        2016-09-26 22:24:12.284664360 +0200
***************
*** 2030,2036 ****
                                any     send {string} over raw {handle}
  ch_setoptions({handle}, {options})
                                none    set options for {handle}
! ch_status({handle})           String  status of channel {handle}
  changenr()                    Number  current change number
  char2nr({expr}[, {utf8}])     Number  ASCII/UTF8 value of first char in {expr}
  cindent({lnum})                       Number  C indent for line {lnum}
--- 2031,2038 ----
                                any     send {string} over raw {handle}
  ch_setoptions({handle}, {options})
                                none    set options for {handle}
! ch_status({handle} [, {options}])
!                               String  status of channel {handle}
  changenr()                    Number  current change number
  char2nr({expr}[, {utf8}])     Number  ASCII/UTF8 value of first char in {expr}
  cindent({lnum})                       Number  C indent for line {lnum}
***************
*** 3041,3047 ****
                Returns a Dictionary with information about {handle}.  The
                items are:
                   "id"           number of the channel
!                  "status"       "open" (any part is open) or "closed"
                When opened with ch_open():
                   "hostname"     the hostname of the address
                   "port"         the port of the address
--- 3043,3050 ----
                Returns a Dictionary with information about {handle}.  The
                items are:
                   "id"           number of the channel
!                  "status"       "open", "buffered" or "closed", like
!                                 ch_status()
                When opened with ch_open():
                   "hostname"     the hostname of the address
                   "port"         the port of the address
***************
*** 3050,3060 ****
                   "sock_io"      "socket"
                   "sock_timeout" timeout in msec
                When opened with job_start():
!                  "out_status"   "open" or "closed"
                   "out_mode"     "NL", "RAW", "JSON" or "JS"
                   "out_io"       "null", "pipe", "file" or "buffer"
                   "out_timeout"  timeout in msec
!                  "err_status"   "open" or "closed"
                   "err_mode"     "NL", "RAW", "JSON" or "JS"
                   "err_io"       "out", "null", "pipe", "file" or "buffer"
                   "err_timeout"  timeout in msec
--- 3053,3063 ----
                   "sock_io"      "socket"
                   "sock_timeout" timeout in msec
                When opened with job_start():
!                  "out_status"   "open", "buffered" or "closed"
                   "out_mode"     "NL", "RAW", "JSON" or "JS"
                   "out_io"       "null", "pipe", "file" or "buffer"
                   "out_timeout"  timeout in msec
!                  "err_status"   "open", "buffered" or "closed"
                   "err_mode"     "NL", "RAW", "JSON" or "JS"
                   "err_io"       "out", "null", "pipe", "file" or "buffer"
                   "err_timeout"  timeout in msec
***************
*** 3139,3145 ****
                These options cannot be changed:
                        "waittime"      only applies to |ch_open()|
  
! ch_status({handle})                                           *ch_status()*
                Return the status of {handle}:
                        "fail"          failed to open the channel
                        "open"          channel can be used
--- 3142,3148 ----
                These options cannot be changed:
                        "waittime"      only applies to |ch_open()|
  
! ch_status({handle} [, {options}])                             *ch_status()*
                Return the status of {handle}:
                        "fail"          failed to open the channel
                        "open"          channel can be used
***************
*** 3149,3154 ****
--- 3152,3162 ----
                "buffered" is used when the channel was closed but there is
                still data that can be obtained with |ch_read()|.
  
+               If {options} is given it can contain a "part" entry to specify
+               the part of the channel to return the status for: "out" or
+               "err".  For example, to get the error status: >
+                       ch_status(job, {"part": "err"})
+ <
                                                        *copy()*
  copy({expr})  Make a copy of {expr}.  For Numbers and Strings this isn't
                different from using {expr} directly.
*** ../vim-8.0.0014/src/version.c       2016-09-26 20:14:49.925906743 +0200
--- src/version.c       2016-09-26 22:15:39.060227458 +0200
***************
*** 766,767 ****
--- 766,769 ----
  {   /* Add new patch number below this line */
+ /**/
+     15,
  /**/

-- 
"A mouse can be just as dangerous as a bullet or a bomb."
             (US Representative Lamar Smith, R-Texas)

 /// 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