Mercurial > vim
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". |