1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * alloc.c: functions for memory management 12 */ 13 14 #include "vim.h" 15 16 /********************************************************************** 17 * Various routines dealing with allocation and deallocation of memory. 18 */ 19 20 #if defined(MEM_PROFILE) || defined(PROTO) 21 22 # define MEM_SIZES 8200 23 static long_u mem_allocs[MEM_SIZES]; 24 static long_u mem_frees[MEM_SIZES]; 25 static long_u mem_allocated; 26 static long_u mem_freed; 27 static long_u mem_peak; 28 static long_u num_alloc; 29 static long_u num_freed; 30 31 static void 32 mem_pre_alloc_s(size_t *sizep) 33 { 34 *sizep += sizeof(size_t); 35 } 36 37 static void 38 mem_pre_alloc_l(size_t *sizep) 39 { 40 *sizep += sizeof(size_t); 41 } 42 43 static void 44 mem_post_alloc( 45 void **pp, 46 size_t size) 47 { 48 if (*pp == NULL) 49 return; 50 size -= sizeof(size_t); 51 *(long_u *)*pp = size; 52 if (size <= MEM_SIZES-1) 53 mem_allocs[size-1]++; 54 else 55 mem_allocs[MEM_SIZES-1]++; 56 mem_allocated += size; 57 if (mem_allocated - mem_freed > mem_peak) 58 mem_peak = mem_allocated - mem_freed; 59 num_alloc++; 60 *pp = (void *)((char *)*pp + sizeof(size_t)); 61 } 62 63 static void 64 mem_pre_free(void **pp) 65 { 66 long_u size; 67 68 *pp = (void *)((char *)*pp - sizeof(size_t)); 69 size = *(size_t *)*pp; 70 if (size <= MEM_SIZES-1) 71 mem_frees[size-1]++; 72 else 73 mem_frees[MEM_SIZES-1]++; 74 mem_freed += size; 75 num_freed++; 76 } 77 78 /* 79 * called on exit via atexit() 80 */ 81 void 82 vim_mem_profile_dump(void) 83 { 84 int i, j; 85 86 printf("\r\n"); 87 j = 0; 88 for (i = 0; i < MEM_SIZES - 1; i++) 89 { 90 if (mem_allocs[i] || mem_frees[i]) 91 { 92 if (mem_frees[i] > mem_allocs[i]) 93 printf("\r\n%s", _("ERROR: ")); 94 printf("[%4d / %4lu-%-4lu] ", i + 1, mem_allocs[i], mem_frees[i]); 95 j++; 96 if (j > 3) 97 { 98 j = 0; 99 printf("\r\n"); 100 } 101 } 102 } 103 104 i = MEM_SIZES - 1; 105 if (mem_allocs[i]) 106 { 107 printf("\r\n"); 108 if (mem_frees[i] > mem_allocs[i]) 109 puts(_("ERROR: ")); 110 printf("[>%d / %4lu-%-4lu]", i, mem_allocs[i], mem_frees[i]); 111 } 112 113 printf(_("\n[bytes] total alloc-freed %lu-%lu, in use %lu, peak use %lu\n"), 114 mem_allocated, mem_freed, mem_allocated - mem_freed, mem_peak); 115 printf(_("[calls] total re/malloc()'s %lu, total free()'s %lu\n\n"), 116 num_alloc, num_freed); 117 } 118 119 #endif // MEM_PROFILE 120 121 #ifdef FEAT_EVAL 122 int 123 alloc_does_fail(size_t size) 124 { 125 if (alloc_fail_countdown == 0) 126 { 127 if (--alloc_fail_repeat <= 0) 128 alloc_fail_id = 0; 129 do_outofmem_msg(size); 130 return TRUE; 131 } 132 --alloc_fail_countdown; 133 return FALSE; 134 } 135 #endif 136 137 /* 138 * Some memory is reserved for error messages and for being able to 139 * call mf_release_all(), which needs some memory for mf_trans_add(). 140 */ 141 #define KEEP_ROOM (2 * 8192L) 142 #define KEEP_ROOM_KB (KEEP_ROOM / 1024L) 143 144 /* 145 * The normal way to allocate memory. This handles an out-of-memory situation 146 * as well as possible, still returns NULL when we're completely out. 147 */ 148 void * 149 alloc(size_t size) 150 { 151 return lalloc(size, TRUE); 152 } 153 154 /* 155 * alloc() with an ID for alloc_fail(). 156 */ 157 void * 158 alloc_id(size_t size, alloc_id_T id UNUSED) 159 { 160 #ifdef FEAT_EVAL 161 if (alloc_fail_id == id && alloc_does_fail(size)) 162 return NULL; 163 #endif 164 return lalloc(size, TRUE); 165 } 166 167 /* 168 * Allocate memory and set all bytes to zero. 169 */ 170 void * 171 alloc_clear(size_t size) 172 { 173 void *p; 174 175 p = lalloc(size, TRUE); 176 if (p != NULL) 177 (void)vim_memset(p, 0, size); 178 return p; 179 } 180 181 /* 182 * Same as alloc_clear() but with allocation id for testing 183 */ 184 void * 185 alloc_clear_id(size_t size, alloc_id_T id UNUSED) 186 { 187 #ifdef FEAT_EVAL 188 if (alloc_fail_id == id && alloc_does_fail(size)) 189 return NULL; 190 #endif 191 return alloc_clear(size); 192 } 193 194 /* 195 * Allocate memory like lalloc() and set all bytes to zero. 196 */ 197 void * 198 lalloc_clear(size_t size, int message) 199 { 200 void *p; 201 202 p = lalloc(size, message); 203 if (p != NULL) 204 (void)vim_memset(p, 0, size); 205 return p; 206 } 207 208 /* 209 * Low level memory allocation function. 210 * This is used often, KEEP IT FAST! 211 */ 212 void * 213 lalloc(size_t size, int message) 214 { 215 void *p; // pointer to new storage space 216 static int releasing = FALSE; // don't do mf_release_all() recursive 217 int try_again; 218 #if defined(HAVE_AVAIL_MEM) 219 static size_t allocated = 0; // allocated since last avail check 220 #endif 221 222 // Safety check for allocating zero bytes 223 if (size == 0) 224 { 225 // Don't hide this message 226 emsg_silent = 0; 227 iemsg(_("E341: Internal error: lalloc(0, )")); 228 return NULL; 229 } 230 231 #ifdef MEM_PROFILE 232 mem_pre_alloc_l(&size); 233 #endif 234 235 // Loop when out of memory: Try to release some memfile blocks and 236 // if some blocks are released call malloc again. 237 for (;;) 238 { 239 // Handle three kind of systems: 240 // 1. No check for available memory: Just return. 241 // 2. Slow check for available memory: call mch_avail_mem() after 242 // allocating KEEP_ROOM amount of memory. 243 // 3. Strict check for available memory: call mch_avail_mem() 244 if ((p = malloc(size)) != NULL) 245 { 246 #ifndef HAVE_AVAIL_MEM 247 // 1. No check for available memory: Just return. 248 goto theend; 249 #else 250 // 2. Slow check for available memory: call mch_avail_mem() after 251 // allocating (KEEP_ROOM / 2) amount of memory. 252 allocated += size; 253 if (allocated < KEEP_ROOM / 2) 254 goto theend; 255 allocated = 0; 256 257 // 3. check for available memory: call mch_avail_mem() 258 if (mch_avail_mem(TRUE) < KEEP_ROOM_KB && !releasing) 259 { 260 free(p); // System is low... no go! 261 p = NULL; 262 } 263 else 264 goto theend; 265 #endif 266 } 267 // Remember that mf_release_all() is being called to avoid an endless 268 // loop, because mf_release_all() may call alloc() recursively. 269 if (releasing) 270 break; 271 releasing = TRUE; 272 273 clear_sb_text(TRUE); // free any scrollback text 274 try_again = mf_release_all(); // release as many blocks as possible 275 276 releasing = FALSE; 277 if (!try_again) 278 break; 279 } 280 281 if (message && p == NULL) 282 do_outofmem_msg(size); 283 284 theend: 285 #ifdef MEM_PROFILE 286 mem_post_alloc(&p, size); 287 #endif 288 return p; 289 } 290 291 /* 292 * lalloc() with an ID for alloc_fail(). 293 */ 294 #if defined(FEAT_SIGNS) || defined(PROTO) 295 void * 296 lalloc_id(size_t size, int message, alloc_id_T id UNUSED) 297 { 298 #ifdef FEAT_EVAL 299 if (alloc_fail_id == id && alloc_does_fail(size)) 300 return NULL; 301 #endif 302 return (lalloc(size, message)); 303 } 304 #endif 305 306 #if defined(MEM_PROFILE) || defined(PROTO) 307 /* 308 * realloc() with memory profiling. 309 */ 310 void * 311 mem_realloc(void *ptr, size_t size) 312 { 313 void *p; 314 315 mem_pre_free(&ptr); 316 mem_pre_alloc_s(&size); 317 318 p = realloc(ptr, size); 319 320 mem_post_alloc(&p, size); 321 322 return p; 323 } 324 #endif 325 326 /* 327 * Avoid repeating the error message many times (they take 1 second each). 328 * Did_outofmem_msg is reset when a character is read. 329 */ 330 void 331 do_outofmem_msg(size_t size) 332 { 333 if (!did_outofmem_msg) 334 { 335 // Don't hide this message 336 emsg_silent = 0; 337 338 // Must come first to avoid coming back here when printing the error 339 // message fails, e.g. when setting v:errmsg. 340 did_outofmem_msg = TRUE; 341 342 semsg(_("E342: Out of memory! (allocating %lu bytes)"), (long_u)size); 343 344 if (starting == NO_SCREEN) 345 // Not even finished with initializations and already out of 346 // memory? Then nothing is going to work, exit. 347 mch_exit(123); 348 } 349 } 350 351 #if defined(EXITFREE) || defined(PROTO) 352 353 /* 354 * Free everything that we allocated. 355 * Can be used to detect memory leaks, e.g., with ccmalloc. 356 * NOTE: This is tricky! Things are freed that functions depend on. Don't be 357 * surprised if Vim crashes... 358 * Some things can't be freed, esp. things local to a library function. 359 */ 360 void 361 free_all_mem(void) 362 { 363 buf_T *buf, *nextbuf; 364 365 // When we cause a crash here it is caught and Vim tries to exit cleanly. 366 // Don't try freeing everything again. 367 if (entered_free_all_mem) 368 return; 369 entered_free_all_mem = TRUE; 370 // Don't want to trigger autocommands from here on. 371 block_autocmds(); 372 373 // Close all tabs and windows. Reset 'equalalways' to avoid redraws. 374 p_ea = FALSE; 375 if (first_tabpage != NULL && first_tabpage->tp_next != NULL) 376 do_cmdline_cmd((char_u *)"tabonly!"); 377 if (!ONE_WINDOW) 378 do_cmdline_cmd((char_u *)"only!"); 379 380 # if defined(FEAT_SPELL) 381 // Free all spell info. 382 spell_free_all(); 383 # endif 384 385 # if defined(FEAT_BEVAL_TERM) 386 ui_remove_balloon(); 387 # endif 388 # ifdef FEAT_PROP_POPUP 389 if (curwin != NULL) 390 close_all_popups(TRUE); 391 # endif 392 393 // Clear user commands (before deleting buffers). 394 ex_comclear(NULL); 395 396 // When exiting from mainerr_arg_missing curbuf has not been initialized, 397 // and not much else. 398 if (curbuf != NULL) 399 { 400 # ifdef FEAT_MENU 401 // Clear menus. 402 do_cmdline_cmd((char_u *)"aunmenu *"); 403 # ifdef FEAT_MULTI_LANG 404 do_cmdline_cmd((char_u *)"menutranslate clear"); 405 # endif 406 # endif 407 // Clear mappings, abbreviations, breakpoints. 408 do_cmdline_cmd((char_u *)"lmapclear"); 409 do_cmdline_cmd((char_u *)"xmapclear"); 410 do_cmdline_cmd((char_u *)"mapclear"); 411 do_cmdline_cmd((char_u *)"mapclear!"); 412 do_cmdline_cmd((char_u *)"abclear"); 413 # if defined(FEAT_EVAL) 414 do_cmdline_cmd((char_u *)"breakdel *"); 415 # endif 416 # if defined(FEAT_PROFILE) 417 do_cmdline_cmd((char_u *)"profdel *"); 418 # endif 419 # if defined(FEAT_KEYMAP) 420 do_cmdline_cmd((char_u *)"set keymap="); 421 # endif 422 } 423 424 # ifdef FEAT_TITLE 425 free_titles(); 426 # endif 427 # if defined(FEAT_SEARCHPATH) 428 free_findfile(); 429 # endif 430 431 // Obviously named calls. 432 free_all_autocmds(); 433 clear_termcodes(); 434 free_all_marks(); 435 alist_clear(&global_alist); 436 free_homedir(); 437 free_users(); 438 free_search_patterns(); 439 free_old_sub(); 440 free_last_insert(); 441 free_insexpand_stuff(); 442 free_prev_shellcmd(); 443 free_regexp_stuff(); 444 free_tag_stuff(); 445 free_cd_dir(); 446 # ifdef FEAT_SIGNS 447 free_signs(); 448 # endif 449 # ifdef FEAT_EVAL 450 set_expr_line(NULL, NULL); 451 # endif 452 # ifdef FEAT_DIFF 453 if (curtab != NULL) 454 diff_clear(curtab); 455 # endif 456 clear_sb_text(TRUE); // free any scrollback text 457 458 // Free some global vars. 459 free_username(); 460 # ifdef FEAT_CLIPBOARD 461 vim_regfree(clip_exclude_prog); 462 # endif 463 vim_free(last_cmdline); 464 vim_free(new_last_cmdline); 465 set_keep_msg(NULL, 0); 466 467 // Clear cmdline history. 468 p_hi = 0; 469 init_history(); 470 # ifdef FEAT_PROP_POPUP 471 clear_global_prop_types(); 472 # endif 473 474 # ifdef FEAT_QUICKFIX 475 { 476 win_T *win; 477 tabpage_T *tab; 478 479 qf_free_all(NULL); 480 // Free all location lists 481 FOR_ALL_TAB_WINDOWS(tab, win) 482 qf_free_all(win); 483 } 484 # endif 485 486 // Close all script inputs. 487 close_all_scripts(); 488 489 if (curwin != NULL) 490 // Destroy all windows. Must come before freeing buffers. 491 win_free_all(); 492 493 // Free all option values. Must come after closing windows. 494 free_all_options(); 495 496 // Free all buffers. Reset 'autochdir' to avoid accessing things that 497 // were freed already. 498 # ifdef FEAT_AUTOCHDIR 499 p_acd = FALSE; 500 # endif 501 for (buf = firstbuf; buf != NULL; ) 502 { 503 bufref_T bufref; 504 505 set_bufref(&bufref, buf); 506 nextbuf = buf->b_next; 507 close_buffer(NULL, buf, DOBUF_WIPE, FALSE, FALSE); 508 if (bufref_valid(&bufref)) 509 buf = nextbuf; // didn't work, try next one 510 else 511 buf = firstbuf; 512 } 513 514 # ifdef FEAT_ARABIC 515 free_arshape_buf(); 516 # endif 517 518 // Clear registers. 519 clear_registers(); 520 ResetRedobuff(); 521 ResetRedobuff(); 522 523 # if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 524 vim_free(serverDelayedStartName); 525 # endif 526 527 // highlight info 528 free_highlight(); 529 530 reset_last_sourcing(); 531 532 if (first_tabpage != NULL) 533 { 534 free_tabpage(first_tabpage); 535 first_tabpage = NULL; 536 } 537 538 # ifdef UNIX 539 // Machine-specific free. 540 mch_free_mem(); 541 # endif 542 543 // message history 544 for (;;) 545 if (delete_first_msg() == FAIL) 546 break; 547 548 # ifdef FEAT_JOB_CHANNEL 549 channel_free_all(); 550 # endif 551 # ifdef FEAT_TIMERS 552 timer_free_all(); 553 # endif 554 # ifdef FEAT_EVAL 555 // must be after channel_free_all() with unrefs partials 556 eval_clear(); 557 # endif 558 # ifdef FEAT_JOB_CHANNEL 559 // must be after eval_clear() with unrefs jobs 560 job_free_all(); 561 # endif 562 563 free_termoptions(); 564 565 // screenlines (can't display anything now!) 566 free_screenlines(); 567 568 # if defined(FEAT_SOUND) 569 sound_free(); 570 # endif 571 # if defined(USE_XSMP) 572 xsmp_close(); 573 # endif 574 # ifdef FEAT_GUI_GTK 575 gui_mch_free_all(); 576 # endif 577 clear_hl_tables(); 578 579 vim_free(IObuff); 580 vim_free(NameBuff); 581 # ifdef FEAT_QUICKFIX 582 check_quickfix_busy(); 583 # endif 584 } 585 #endif 586 587 /* 588 * Copy "p[len]" into allocated memory, ignoring NUL characters. 589 * Returns NULL when out of memory. 590 */ 591 char_u * 592 vim_memsave(char_u *p, size_t len) 593 { 594 char_u *ret = alloc(len); 595 596 if (ret != NULL) 597 mch_memmove(ret, p, len); 598 return ret; 599 } 600 601 /* 602 * Replacement for free() that ignores NULL pointers. 603 * Also skip free() when exiting for sure, this helps when we caught a deadly 604 * signal that was caused by a crash in free(). 605 * If you want to set NULL after calling this function, you should use 606 * VIM_CLEAR() instead. 607 */ 608 void 609 vim_free(void *x) 610 { 611 if (x != NULL && !really_exiting) 612 { 613 #ifdef MEM_PROFILE 614 mem_pre_free(&x); 615 #endif 616 free(x); 617 } 618 } 619 620 /************************************************************************ 621 * Functions for handling growing arrays. 622 */ 623 624 /* 625 * Clear an allocated growing array. 626 */ 627 void 628 ga_clear(garray_T *gap) 629 { 630 vim_free(gap->ga_data); 631 ga_init(gap); 632 } 633 634 /* 635 * Clear a growing array that contains a list of strings. 636 */ 637 void 638 ga_clear_strings(garray_T *gap) 639 { 640 int i; 641 642 if (gap->ga_data != NULL) 643 for (i = 0; i < gap->ga_len; ++i) 644 vim_free(((char_u **)(gap->ga_data))[i]); 645 ga_clear(gap); 646 } 647 648 /* 649 * Copy a growing array that contains a list of strings. 650 */ 651 int 652 ga_copy_strings(garray_T *from, garray_T *to) 653 { 654 int i; 655 656 ga_init2(to, sizeof(char_u *), 1); 657 if (ga_grow(to, from->ga_len) == FAIL) 658 return FAIL; 659 660 for (i = 0; i < from->ga_len; ++i) 661 { 662 char_u *orig = ((char_u **)from->ga_data)[i]; 663 char_u *copy; 664 665 if (orig == NULL) 666 copy = NULL; 667 else 668 { 669 copy = vim_strsave(orig); 670 if (copy == NULL) 671 { 672 to->ga_len = i; 673 ga_clear_strings(to); 674 return FAIL; 675 } 676 } 677 ((char_u **)to->ga_data)[i] = copy; 678 } 679 to->ga_len = from->ga_len; 680 return OK; 681 } 682 683 /* 684 * Initialize a growing array. Don't forget to set ga_itemsize and 685 * ga_growsize! Or use ga_init2(). 686 */ 687 void 688 ga_init(garray_T *gap) 689 { 690 gap->ga_data = NULL; 691 gap->ga_maxlen = 0; 692 gap->ga_len = 0; 693 } 694 695 void 696 ga_init2(garray_T *gap, int itemsize, int growsize) 697 { 698 ga_init(gap); 699 gap->ga_itemsize = itemsize; 700 gap->ga_growsize = growsize; 701 } 702 703 /* 704 * Make room in growing array "gap" for at least "n" items. 705 * Return FAIL for failure, OK otherwise. 706 */ 707 int 708 ga_grow(garray_T *gap, int n) 709 { 710 if (gap->ga_maxlen - gap->ga_len < n) 711 return ga_grow_inner(gap, n); 712 return OK; 713 } 714 715 int 716 ga_grow_inner(garray_T *gap, int n) 717 { 718 size_t old_len; 719 size_t new_len; 720 char_u *pp; 721 722 if (n < gap->ga_growsize) 723 n = gap->ga_growsize; 724 725 // A linear growth is very inefficient when the array grows big. This 726 // is a compromise between allocating memory that won't be used and too 727 // many copy operations. A factor of 1.5 seems reasonable. 728 if (n < gap->ga_len / 2) 729 n = gap->ga_len / 2; 730 731 new_len = gap->ga_itemsize * (gap->ga_len + n); 732 pp = vim_realloc(gap->ga_data, new_len); 733 if (pp == NULL) 734 return FAIL; 735 old_len = gap->ga_itemsize * gap->ga_maxlen; 736 vim_memset(pp + old_len, 0, new_len - old_len); 737 gap->ga_maxlen = gap->ga_len + n; 738 gap->ga_data = pp; 739 return OK; 740 } 741 742 /* 743 * For a growing array that contains a list of strings: concatenate all the 744 * strings with a separating "sep". 745 * Returns NULL when out of memory. 746 */ 747 char_u * 748 ga_concat_strings(garray_T *gap, char *sep) 749 { 750 int i; 751 int len = 0; 752 int sep_len = (int)STRLEN(sep); 753 char_u *s; 754 char_u *p; 755 756 for (i = 0; i < gap->ga_len; ++i) 757 len += (int)STRLEN(((char_u **)(gap->ga_data))[i]) + sep_len; 758 759 s = alloc(len + 1); 760 if (s != NULL) 761 { 762 *s = NUL; 763 p = s; 764 for (i = 0; i < gap->ga_len; ++i) 765 { 766 if (p != s) 767 { 768 STRCPY(p, sep); 769 p += sep_len; 770 } 771 STRCPY(p, ((char_u **)(gap->ga_data))[i]); 772 p += STRLEN(p); 773 } 774 } 775 return s; 776 } 777 778 /* 779 * Make a copy of string "p" and add it to "gap". 780 * When out of memory nothing changes and FAIL is returned. 781 */ 782 int 783 ga_add_string(garray_T *gap, char_u *p) 784 { 785 char_u *cp = vim_strsave(p); 786 787 if (cp == NULL) 788 return FAIL; 789 790 if (ga_grow(gap, 1) == FAIL) 791 { 792 vim_free(cp); 793 return FAIL; 794 } 795 ((char_u **)(gap->ga_data))[gap->ga_len++] = cp; 796 return OK; 797 } 798 799 /* 800 * Concatenate a string to a growarray which contains bytes. 801 * When "s" is NULL does not do anything. 802 * Note: Does NOT copy the NUL at the end! 803 */ 804 void 805 ga_concat(garray_T *gap, char_u *s) 806 { 807 int len; 808 809 if (s == NULL || *s == NUL) 810 return; 811 len = (int)STRLEN(s); 812 if (ga_grow(gap, len) == OK) 813 { 814 mch_memmove((char *)gap->ga_data + gap->ga_len, s, (size_t)len); 815 gap->ga_len += len; 816 } 817 } 818 819 /* 820 * Concatenate 'len' bytes from string 's' to a growarray. 821 * When "s" is NULL does not do anything. 822 */ 823 void 824 ga_concat_len(garray_T *gap, char_u *s, size_t len) 825 { 826 if (s == NULL || *s == NUL) 827 return; 828 if (ga_grow(gap, (int)len) == OK) 829 { 830 mch_memmove((char *)gap->ga_data + gap->ga_len, s, len); 831 gap->ga_len += (int)len; 832 } 833 } 834 835 /* 836 * Append one byte to a growarray which contains bytes. 837 */ 838 void 839 ga_append(garray_T *gap, int c) 840 { 841 if (ga_grow(gap, 1) == OK) 842 { 843 *((char *)gap->ga_data + gap->ga_len) = c; 844 ++gap->ga_len; 845 } 846 } 847 848 #if (defined(UNIX) && !defined(USE_SYSTEM)) || defined(MSWIN) \ 849 || defined(PROTO) 850 /* 851 * Append the text in "gap" below the cursor line and clear "gap". 852 */ 853 void 854 append_ga_line(garray_T *gap) 855 { 856 // Remove trailing CR. 857 if (gap->ga_len > 0 858 && !curbuf->b_p_bin 859 && ((char_u *)gap->ga_data)[gap->ga_len - 1] == CAR) 860 --gap->ga_len; 861 ga_append(gap, NUL); 862 ml_append(curwin->w_cursor.lnum++, gap->ga_data, 0, FALSE); 863 gap->ga_len = 0; 864 } 865 #endif 866 867