To: vim_dev@googlegroups.com Subject: Patch 8.0.0015 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@Moolenaar.net -- 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 ///