Mercurial > vim
comparison src/channel.c @ 8759:cc2ef7367643 v7.4.1668
commit https://github.com/vim/vim/commit/ee1f7b3cb71684aaa9bf457e2caf9d02187e6b7c
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Mar 28 14:42:14 2016 +0200
patch 7.4.1668
Problem: channel_get_all() does multiple allocations.
Solution: Compute the size and allocate once.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 28 Mar 2016 14:45:04 +0200 |
parents | 4fb37555e814 |
children | f8707ec9efe4 |
comparison
equal
deleted
inserted
replaced
8758:b9b73c04e542 | 8759:cc2ef7367643 |
---|---|
432 } | 432 } |
433 #endif | 433 #endif |
434 | 434 |
435 /* | 435 /* |
436 * Read a command from netbeans. | 436 * Read a command from netbeans. |
437 * TODO: instead of channel ID use the FD. | |
438 */ | 437 */ |
439 #ifdef FEAT_GUI_X11 | 438 #ifdef FEAT_GUI_X11 |
440 static void | 439 static void |
441 messageFromNetbeans(XtPointer clientData, | 440 messageFromNetbeans(XtPointer clientData, |
442 int *unused1 UNUSED, | 441 int *unused1 UNUSED, |
1323 * Returns the whole buffer contents concatenated for "channel"/"part". | 1322 * Returns the whole buffer contents concatenated for "channel"/"part". |
1324 */ | 1323 */ |
1325 static char_u * | 1324 static char_u * |
1326 channel_get_all(channel_T *channel, int part) | 1325 channel_get_all(channel_T *channel, int part) |
1327 { | 1326 { |
1328 /* Concatenate everything into one buffer. | 1327 readq_T *head = &channel->ch_part[part].ch_head; |
1329 * TODO: avoid multiple allocations. */ | 1328 readq_T *node = head->rq_next; |
1330 while (channel_collapse(channel, part) == OK) | 1329 long_u len = 1; |
1331 ; | 1330 char_u *res; |
1332 return channel_get(channel, part); | 1331 char_u *p; |
1332 | |
1333 /* If there is only one buffer just get that one. */ | |
1334 if (head->rq_next == NULL || head->rq_next->rq_next == NULL) | |
1335 return channel_get(channel, part); | |
1336 | |
1337 /* Concatenate everything into one buffer. */ | |
1338 for (node = head->rq_next; node != NULL; node = node->rq_next) | |
1339 len += (long_u)STRLEN(node->rq_buffer); | |
1340 res = lalloc(len, TRUE); | |
1341 if (res == NULL) | |
1342 return NULL; | |
1343 *res = NUL; | |
1344 for (node = head->rq_next; node != NULL; node = node->rq_next) | |
1345 STRCAT(res, node->rq_buffer); | |
1346 | |
1347 /* Free all buffers */ | |
1348 do | |
1349 { | |
1350 p = channel_get(channel, part); | |
1351 vim_free(p); | |
1352 } while (p != NULL); | |
1353 | |
1354 return res; | |
1333 } | 1355 } |
1334 | 1356 |
1335 /* | 1357 /* |
1336 * Collapses the first and second buffer for "channel"/"part". | 1358 * Collapses the first and second buffer for "channel"/"part". |
1337 * Returns FAIL if that is not possible. | 1359 * Returns FAIL if that is not possible. |
2502 if (channel->ch_part[part].ch_mode == MODE_RAW | 2524 if (channel->ch_part[part].ch_mode == MODE_RAW |
2503 || channel->ch_part[part].ch_mode == MODE_NL) | 2525 || channel->ch_part[part].ch_mode == MODE_NL) |
2504 channel_save(channel, part, (char_u *)DETACH_MSG_RAW, | 2526 channel_save(channel, part, (char_u *)DETACH_MSG_RAW, |
2505 (int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT "); | 2527 (int)STRLEN(DETACH_MSG_RAW), FALSE, "PUT "); |
2506 | 2528 |
2507 /* TODO: When reading from stdout is not possible, should we try to | 2529 /* When reading from stdout is not possible, assume the other side has |
2508 * keep stdin and stderr open? Probably not, assume the other side | 2530 * died. */ |
2509 * has died. */ | |
2510 channel_close(channel, TRUE); | 2531 channel_close(channel, TRUE); |
2511 if (channel->ch_nb_close_cb != NULL) | 2532 if (channel->ch_nb_close_cb != NULL) |
2512 (*channel->ch_nb_close_cb)(); | 2533 (*channel->ch_nb_close_cb)(); |
2513 } | 2534 } |
2514 | 2535 |