comparison src/channel.c @ 8084:3ea56a74077f v7.4.1336

commit https://github.com/vim/vim/commit/9a6e33a19b18f20c25b73392cd2faa3ec4890c8c Author: Bram Moolenaar <Bram@vim.org> Date: Tue Feb 16 19:25:12 2016 +0100 patch 7.4.1336 Problem: Channel NL mode is not supported yet. Solution: Add NL mode support to channels.
author Christian Brabandt <cb@256bit.org>
date Tue, 16 Feb 2016 19:30:05 +0100
parents b6cb94ad97a4
children 18a3f0f05244
comparison
equal deleted inserted replaced
8083:56fcca2c82a2 8084:3ea56a74077f
667 { 667 {
668 channel->ch_job = job; 668 channel->ch_job = job;
669 } 669 }
670 670
671 /* 671 /*
672 * Set the json mode of channel "channel" to "ch_mode". 672 * Set the mode of channel "channel" to "mode".
673 */ 673 */
674 void 674 void
675 channel_set_json_mode(channel_T *channel, ch_mode_T ch_mode) 675 channel_set_mode(channel_T *channel, ch_mode_T mode)
676 { 676 {
677 channel->ch_mode = ch_mode; 677 channel->ch_mode = mode;
678 } 678 }
679 679
680 /* 680 /*
681 * Set the read timeout of channel "channel". 681 * Set the read timeout of channel "channel".
682 */ 682 */
1055 EMSG2("E905: received unknown command: %s", cmd); 1055 EMSG2("E905: received unknown command: %s", cmd);
1056 } 1056 }
1057 1057
1058 /* 1058 /*
1059 * Invoke a callback for channel "channel" if needed. 1059 * Invoke a callback for channel "channel" if needed.
1060 * Return OK when a message was handled, there might be another one. 1060 * TODO: add "which" argument, read stderr.
1061 * Return TRUE when a message was handled, there might be another one.
1061 */ 1062 */
1062 static int 1063 static int
1063 may_invoke_callback(channel_T *channel) 1064 may_invoke_callback(channel_T *channel)
1064 { 1065 {
1065 char_u *msg = NULL; 1066 char_u *msg = NULL;
1072 1073
1073 if (channel->ch_close_cb != NULL) 1074 if (channel->ch_close_cb != NULL)
1074 /* this channel is handled elsewhere (netbeans) */ 1075 /* this channel is handled elsewhere (netbeans) */
1075 return FALSE; 1076 return FALSE;
1076 1077
1077 if (ch_mode != MODE_RAW) 1078 if (ch_mode == MODE_JSON || ch_mode == MODE_JS)
1078 { 1079 {
1079 /* Get any json message in the queue. */ 1080 /* Get any json message in the queue. */
1080 if (channel_get_json(channel, -1, &listtv) == FAIL) 1081 if (channel_get_json(channel, -1, &listtv) == FAIL)
1081 { 1082 {
1082 /* Parse readahead, return when there is still no message. */ 1083 /* Parse readahead, return when there is still no message. */
1111 } 1112 }
1112 seq_nr = typetv->vval.v_number; 1113 seq_nr = typetv->vval.v_number;
1113 } 1114 }
1114 else if (channel_peek(channel) == NULL) 1115 else if (channel_peek(channel) == NULL)
1115 { 1116 {
1116 /* nothing to read on raw channel */ 1117 /* nothing to read on RAW or NL channel */
1117 return FALSE; 1118 return FALSE;
1118 } 1119 }
1119 else 1120 else
1120 { 1121 {
1121 /* If there is no callback, don't do anything. */ 1122 /* If there is no callback drop the message. */
1122 if (channel->ch_callback == NULL) 1123 if (channel->ch_callback == NULL)
1124 {
1125 while ((msg = channel_get(channel)) != NULL)
1126 vim_free(msg);
1123 return FALSE; 1127 return FALSE;
1124 1128 }
1125 /* For a raw channel we don't know where the message ends, just get 1129
1126 * everything. */ 1130 if (ch_mode == MODE_NL)
1127 msg = channel_get_all(channel); 1131 {
1132 char_u *nl;
1133 char_u *buf;
1134
1135 /* See if we have a message ending in NL in the first buffer. If
1136 * not try to concatenate the first and the second buffer. */
1137 while (TRUE)
1138 {
1139 buf = channel_peek(channel);
1140 nl = vim_strchr(buf, NL);
1141 if (nl != NULL)
1142 break;
1143 if (channel_collapse(channel) == FAIL)
1144 return FALSE; /* incomplete message */
1145 }
1146 if (nl[1] == NUL)
1147 /* get the whole buffer */
1148 msg = channel_get(channel);
1149 else
1150 {
1151 /* Copy the message into allocated memory and remove it from
1152 * the buffer. */
1153 msg = vim_strnsave(buf, (int)(nl - buf));
1154 mch_memmove(buf, nl + 1, STRLEN(nl + 1) + 1);
1155 }
1156 }
1157 else
1158 /* For a raw channel we don't know where the message ends, just
1159 * get everything we have. */
1160 msg = channel_get_all(channel);
1161
1128 argv[1].v_type = VAR_STRING; 1162 argv[1].v_type = VAR_STRING;
1129 argv[1].vval.v_string = msg; 1163 argv[1].vval.v_string = msg;
1130 } 1164 }
1131 1165
1132 if (seq_nr > 0) 1166 if (seq_nr > 0)
1274 { 1308 {
1275 vim_free(node); 1309 vim_free(node);
1276 return FAIL; /* out of memory */ 1310 return FAIL; /* out of memory */
1277 } 1311 }
1278 1312
1279 /* TODO: don't strip CR when channel is in raw mode */ 1313 if (channel->ch_mode == MODE_NL)
1280 p = node->rq_buffer; 1314 {
1281 for (i = 0; i < len; ++i) 1315 /* Drop any CR before a NL. */
1282 if (buf[i] != CAR || i + 1 >= len || buf[i + 1] != NL) 1316 p = node->rq_buffer;
1283 *p++ = buf[i]; 1317 for (i = 0; i < len; ++i)
1284 *p = NUL; 1318 if (buf[i] != CAR || i + 1 >= len || buf[i + 1] != NL)
1319 *p++ = buf[i];
1320 *p = NUL;
1321 }
1322 else
1323 {
1324 mch_memmove(node->rq_buffer, buf, len);
1325 node->rq_buffer[len] = NUL;
1326 }
1285 1327
1286 /* append node to the tail of the queue */ 1328 /* append node to the tail of the queue */
1287 node->rq_next = NULL; 1329 node->rq_next = NULL;
1288 node->rq_prev = head->rq_prev; 1330 node->rq_prev = head->rq_prev;
1289 if (head->rq_prev == NULL) 1331 if (head->rq_prev == NULL)
1568 gtk_main_quit(); 1610 gtk_main_quit();
1569 #endif 1611 #endif
1570 } 1612 }
1571 1613
1572 /* 1614 /*
1573 * Read from raw channel "channel". Blocks until there is something to read or 1615 * Read from RAW or NL channel "channel". Blocks until there is something to
1574 * the timeout expires. 1616 * read or the timeout expires.
1617 * TODO: add "which" argument and read from stderr.
1575 * Returns what was read in allocated memory. 1618 * Returns what was read in allocated memory.
1576 * Returns NULL in case of error or timeout. 1619 * Returns NULL in case of error or timeout.
1577 */ 1620 */
1578 char_u * 1621 char_u *
1579 channel_read_block(channel_T *channel) 1622 channel_read_block(channel_T *channel)
1580 { 1623 {
1581 ch_log(channel, "Reading raw\n"); 1624 char_u *buf;
1582 if (channel_peek(channel) == NULL) 1625 char_u *msg;
1583 { 1626 ch_mode_T mode = channel->ch_mode;
1584 sock_T fd = get_read_fd(channel); 1627 sock_T fd = get_read_fd(channel);
1585 1628 char_u *nl;
1586 /* TODO: read both out and err if they are different */ 1629
1587 ch_log(channel, "No readahead\n"); 1630 ch_logsn(channel, "Blocking %s read, timeout: %d msec\n",
1631 mode == MODE_RAW ? "RAW" : "NL", channel->ch_timeout);
1632
1633 while (TRUE)
1634 {
1635 buf = channel_peek(channel);
1636 if (buf != NULL && (mode == MODE_RAW
1637 || (mode == MODE_NL && vim_strchr(buf, NL) != NULL)))
1638 break;
1639 if (buf != NULL && channel_collapse(channel) == OK)
1640 continue;
1641
1588 /* Wait for up to the channel timeout. */ 1642 /* Wait for up to the channel timeout. */
1589 if (fd == CHAN_FD_INVALID 1643 if (fd == CHAN_FD_INVALID
1590 || channel_wait(channel, fd, channel->ch_timeout) == FAIL) 1644 || channel_wait(channel, fd, channel->ch_timeout) == FAIL)
1591 return NULL; 1645 return NULL;
1592 channel_read(channel, -1, "channel_read_block"); 1646 channel_read(channel, -1, "channel_read_block");
1593 } 1647 }
1594 1648
1595 /* TODO: only get the first message */ 1649 if (mode == MODE_RAW)
1596 ch_log(channel, "Returning readahead\n"); 1650 {
1597 return channel_get_all(channel); 1651 msg = channel_get_all(channel);
1652 }
1653 else
1654 {
1655 nl = vim_strchr(buf, NL);
1656 if (nl[1] == NUL)
1657 {
1658 /* get the whole buffer */
1659 msg = channel_get(channel);
1660 *nl = NUL;
1661 }
1662 else
1663 {
1664 /* Copy the message into allocated memory and remove it from the
1665 * buffer. */
1666 msg = vim_strnsave(buf, (int)(nl - buf));
1667 mch_memmove(buf, nl + 1, STRLEN(nl + 1) + 1);
1668 }
1669 }
1670 if (log_fd != NULL)
1671 ch_logn(channel, "Returning %d bytes\n", (int)STRLEN(msg));
1672 return msg;
1598 } 1673 }
1599 1674
1600 /* 1675 /*
1601 * Read one JSON message with ID "id" from channel "channel" and store the 1676 * Read one JSON message with ID "id" from channel "channel" and store the
1602 * result in "rettv". 1677 * result in "rettv".