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 * list.c: List support 12 */ 13 14 #include "vim.h" 15 16 #if defined(FEAT_EVAL) || defined(PROTO) 17 18 /* List heads for garbage collection. */ 19 static list_T *first_list = NULL; /* list of all lists */ 20 21 /* 22 * Add a watcher to a list. 23 */ 24 void 25 list_add_watch(list_T *l, listwatch_T *lw) 26 { 27 lw->lw_next = l->lv_watch; 28 l->lv_watch = lw; 29 } 30 31 /* 32 * Remove a watcher from a list. 33 * No warning when it isn't found... 34 */ 35 void 36 list_rem_watch(list_T *l, listwatch_T *lwrem) 37 { 38 listwatch_T *lw, **lwp; 39 40 lwp = &l->lv_watch; 41 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 42 { 43 if (lw == lwrem) 44 { 45 *lwp = lw->lw_next; 46 break; 47 } 48 lwp = &lw->lw_next; 49 } 50 } 51 52 /* 53 * Just before removing an item from a list: advance watchers to the next 54 * item. 55 */ 56 void 57 list_fix_watch(list_T *l, listitem_T *item) 58 { 59 listwatch_T *lw; 60 61 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 62 if (lw->lw_item == item) 63 lw->lw_item = item->li_next; 64 } 65 66 /* 67 * Allocate an empty header for a list. 68 * Caller should take care of the reference count. 69 */ 70 list_T * 71 list_alloc(void) 72 { 73 list_T *l; 74 75 l = (list_T *)alloc_clear(sizeof(list_T)); 76 if (l != NULL) 77 { 78 /* Prepend the list to the list of lists for garbage collection. */ 79 if (first_list != NULL) 80 first_list->lv_used_prev = l; 81 l->lv_used_prev = NULL; 82 l->lv_used_next = first_list; 83 first_list = l; 84 } 85 return l; 86 } 87 88 /* 89 * list_alloc() with an ID for alloc_fail(). 90 */ 91 list_T * 92 list_alloc_id(alloc_id_T id UNUSED) 93 { 94 #ifdef FEAT_EVAL 95 if (alloc_fail_id == id && alloc_does_fail((long_u)sizeof(list_T))) 96 return NULL; 97 #endif 98 return (list_alloc()); 99 } 100 101 /* 102 * Allocate an empty list for a return value, with reference count set. 103 * Returns OK or FAIL. 104 */ 105 int 106 rettv_list_alloc(typval_T *rettv) 107 { 108 list_T *l = list_alloc(); 109 110 if (l == NULL) 111 return FAIL; 112 113 rettv->v_lock = 0; 114 rettv_list_set(rettv, l); 115 return OK; 116 } 117 118 /* 119 * Same as rettv_list_alloc() but uses an allocation id for testing. 120 */ 121 int 122 rettv_list_alloc_id(typval_T *rettv, alloc_id_T id UNUSED) 123 { 124 #ifdef FEAT_EVAL 125 if (alloc_fail_id == id && alloc_does_fail((long_u)sizeof(list_T))) 126 return FAIL; 127 #endif 128 return rettv_list_alloc(rettv); 129 } 130 131 132 /* 133 * Set a list as the return value 134 */ 135 void 136 rettv_list_set(typval_T *rettv, list_T *l) 137 { 138 rettv->v_type = VAR_LIST; 139 rettv->vval.v_list = l; 140 if (l != NULL) 141 ++l->lv_refcount; 142 } 143 144 /* 145 * Unreference a list: decrement the reference count and free it when it 146 * becomes zero. 147 */ 148 void 149 list_unref(list_T *l) 150 { 151 if (l != NULL && --l->lv_refcount <= 0) 152 list_free(l); 153 } 154 155 /* 156 * Free a list, including all non-container items it points to. 157 * Ignores the reference count. 158 */ 159 static void 160 list_free_contents(list_T *l) 161 { 162 listitem_T *item; 163 164 for (item = l->lv_first; item != NULL; item = l->lv_first) 165 { 166 /* Remove the item before deleting it. */ 167 l->lv_first = item->li_next; 168 clear_tv(&item->li_tv); 169 vim_free(item); 170 } 171 } 172 173 /* 174 * Go through the list of lists and free items without the copyID. 175 * But don't free a list that has a watcher (used in a for loop), these 176 * are not referenced anywhere. 177 */ 178 int 179 list_free_nonref(int copyID) 180 { 181 list_T *ll; 182 int did_free = FALSE; 183 184 for (ll = first_list; ll != NULL; ll = ll->lv_used_next) 185 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) 186 && ll->lv_watch == NULL) 187 { 188 /* Free the List and ordinary items it contains, but don't recurse 189 * into Lists and Dictionaries, they will be in the list of dicts 190 * or list of lists. */ 191 list_free_contents(ll); 192 did_free = TRUE; 193 } 194 return did_free; 195 } 196 197 static void 198 list_free_list(list_T *l) 199 { 200 /* Remove the list from the list of lists for garbage collection. */ 201 if (l->lv_used_prev == NULL) 202 first_list = l->lv_used_next; 203 else 204 l->lv_used_prev->lv_used_next = l->lv_used_next; 205 if (l->lv_used_next != NULL) 206 l->lv_used_next->lv_used_prev = l->lv_used_prev; 207 208 vim_free(l); 209 } 210 211 void 212 list_free_items(int copyID) 213 { 214 list_T *ll, *ll_next; 215 216 for (ll = first_list; ll != NULL; ll = ll_next) 217 { 218 ll_next = ll->lv_used_next; 219 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) 220 && ll->lv_watch == NULL) 221 { 222 /* Free the List and ordinary items it contains, but don't recurse 223 * into Lists and Dictionaries, they will be in the list of dicts 224 * or list of lists. */ 225 list_free_list(ll); 226 } 227 } 228 } 229 230 void 231 list_free(list_T *l) 232 { 233 if (!in_free_unref_items) 234 { 235 list_free_contents(l); 236 list_free_list(l); 237 } 238 } 239 240 /* 241 * Allocate a list item. 242 * It is not initialized, don't forget to set v_lock. 243 */ 244 listitem_T * 245 listitem_alloc(void) 246 { 247 return (listitem_T *)alloc(sizeof(listitem_T)); 248 } 249 250 /* 251 * Free a list item. Also clears the value. Does not notify watchers. 252 */ 253 void 254 listitem_free(listitem_T *item) 255 { 256 clear_tv(&item->li_tv); 257 vim_free(item); 258 } 259 260 /* 261 * Remove a list item from a List and free it. Also clears the value. 262 */ 263 void 264 listitem_remove(list_T *l, listitem_T *item) 265 { 266 vimlist_remove(l, item, item); 267 listitem_free(item); 268 } 269 270 /* 271 * Get the number of items in a list. 272 */ 273 long 274 list_len(list_T *l) 275 { 276 if (l == NULL) 277 return 0L; 278 return l->lv_len; 279 } 280 281 /* 282 * Return TRUE when two lists have exactly the same values. 283 */ 284 int 285 list_equal( 286 list_T *l1, 287 list_T *l2, 288 int ic, /* ignore case for strings */ 289 int recursive) /* TRUE when used recursively */ 290 { 291 listitem_T *item1, *item2; 292 293 if (l1 == NULL || l2 == NULL) 294 return FALSE; 295 if (l1 == l2) 296 return TRUE; 297 if (list_len(l1) != list_len(l2)) 298 return FALSE; 299 300 for (item1 = l1->lv_first, item2 = l2->lv_first; 301 item1 != NULL && item2 != NULL; 302 item1 = item1->li_next, item2 = item2->li_next) 303 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive)) 304 return FALSE; 305 return item1 == NULL && item2 == NULL; 306 } 307 308 /* 309 * Locate item with index "n" in list "l" and return it. 310 * A negative index is counted from the end; -1 is the last item. 311 * Returns NULL when "n" is out of range. 312 */ 313 listitem_T * 314 list_find(list_T *l, long n) 315 { 316 listitem_T *item; 317 long idx; 318 319 if (l == NULL) 320 return NULL; 321 322 /* Negative index is relative to the end. */ 323 if (n < 0) 324 n = l->lv_len + n; 325 326 /* Check for index out of range. */ 327 if (n < 0 || n >= l->lv_len) 328 return NULL; 329 330 /* When there is a cached index may start search from there. */ 331 if (l->lv_idx_item != NULL) 332 { 333 if (n < l->lv_idx / 2) 334 { 335 /* closest to the start of the list */ 336 item = l->lv_first; 337 idx = 0; 338 } 339 else if (n > (l->lv_idx + l->lv_len) / 2) 340 { 341 /* closest to the end of the list */ 342 item = l->lv_last; 343 idx = l->lv_len - 1; 344 } 345 else 346 { 347 /* closest to the cached index */ 348 item = l->lv_idx_item; 349 idx = l->lv_idx; 350 } 351 } 352 else 353 { 354 if (n < l->lv_len / 2) 355 { 356 /* closest to the start of the list */ 357 item = l->lv_first; 358 idx = 0; 359 } 360 else 361 { 362 /* closest to the end of the list */ 363 item = l->lv_last; 364 idx = l->lv_len - 1; 365 } 366 } 367 368 while (n > idx) 369 { 370 /* search forward */ 371 item = item->li_next; 372 ++idx; 373 } 374 while (n < idx) 375 { 376 /* search backward */ 377 item = item->li_prev; 378 --idx; 379 } 380 381 /* cache the used index */ 382 l->lv_idx = idx; 383 l->lv_idx_item = item; 384 385 return item; 386 } 387 388 /* 389 * Get list item "l[idx]" as a number. 390 */ 391 long 392 list_find_nr( 393 list_T *l, 394 long idx, 395 int *errorp) /* set to TRUE when something wrong */ 396 { 397 listitem_T *li; 398 399 li = list_find(l, idx); 400 if (li == NULL) 401 { 402 if (errorp != NULL) 403 *errorp = TRUE; 404 return -1L; 405 } 406 return (long)tv_get_number_chk(&li->li_tv, errorp); 407 } 408 409 /* 410 * Get list item "l[idx - 1]" as a string. Returns NULL for failure. 411 */ 412 char_u * 413 list_find_str(list_T *l, long idx) 414 { 415 listitem_T *li; 416 417 li = list_find(l, idx - 1); 418 if (li == NULL) 419 { 420 semsg(_(e_listidx), idx); 421 return NULL; 422 } 423 return tv_get_string(&li->li_tv); 424 } 425 426 /* 427 * Locate "item" list "l" and return its index. 428 * Returns -1 when "item" is not in the list. 429 */ 430 long 431 list_idx_of_item(list_T *l, listitem_T *item) 432 { 433 long idx = 0; 434 listitem_T *li; 435 436 if (l == NULL) 437 return -1; 438 idx = 0; 439 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 440 ++idx; 441 if (li == NULL) 442 return -1; 443 return idx; 444 } 445 446 /* 447 * Append item "item" to the end of list "l". 448 */ 449 void 450 list_append(list_T *l, listitem_T *item) 451 { 452 if (l->lv_last == NULL) 453 { 454 /* empty list */ 455 l->lv_first = item; 456 l->lv_last = item; 457 item->li_prev = NULL; 458 } 459 else 460 { 461 l->lv_last->li_next = item; 462 item->li_prev = l->lv_last; 463 l->lv_last = item; 464 } 465 ++l->lv_len; 466 item->li_next = NULL; 467 } 468 469 /* 470 * Append typval_T "tv" to the end of list "l". 471 * Return FAIL when out of memory. 472 */ 473 int 474 list_append_tv(list_T *l, typval_T *tv) 475 { 476 listitem_T *li = listitem_alloc(); 477 478 if (li == NULL) 479 return FAIL; 480 copy_tv(tv, &li->li_tv); 481 list_append(l, li); 482 return OK; 483 } 484 485 /* 486 * Add a dictionary to a list. Used by getqflist(). 487 * Return FAIL when out of memory. 488 */ 489 int 490 list_append_dict(list_T *list, dict_T *dict) 491 { 492 listitem_T *li = listitem_alloc(); 493 494 if (li == NULL) 495 return FAIL; 496 li->li_tv.v_type = VAR_DICT; 497 li->li_tv.v_lock = 0; 498 li->li_tv.vval.v_dict = dict; 499 list_append(list, li); 500 ++dict->dv_refcount; 501 return OK; 502 } 503 504 /* 505 * Append list2 to list1. 506 * Return FAIL when out of memory. 507 */ 508 int 509 list_append_list(list_T *list1, list_T *list2) 510 { 511 listitem_T *li = listitem_alloc(); 512 513 if (li == NULL) 514 return FAIL; 515 li->li_tv.v_type = VAR_LIST; 516 li->li_tv.v_lock = 0; 517 li->li_tv.vval.v_list = list2; 518 list_append(list1, li); 519 ++list2->lv_refcount; 520 return OK; 521 } 522 523 /* 524 * Make a copy of "str" and append it as an item to list "l". 525 * When "len" >= 0 use "str[len]". 526 * Returns FAIL when out of memory. 527 */ 528 int 529 list_append_string(list_T *l, char_u *str, int len) 530 { 531 listitem_T *li = listitem_alloc(); 532 533 if (li == NULL) 534 return FAIL; 535 list_append(l, li); 536 li->li_tv.v_type = VAR_STRING; 537 li->li_tv.v_lock = 0; 538 if (str == NULL) 539 li->li_tv.vval.v_string = NULL; 540 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) 541 : vim_strsave(str))) == NULL) 542 return FAIL; 543 return OK; 544 } 545 546 /* 547 * Append "n" to list "l". 548 * Returns FAIL when out of memory. 549 */ 550 int 551 list_append_number(list_T *l, varnumber_T n) 552 { 553 listitem_T *li; 554 555 li = listitem_alloc(); 556 if (li == NULL) 557 return FAIL; 558 li->li_tv.v_type = VAR_NUMBER; 559 li->li_tv.v_lock = 0; 560 li->li_tv.vval.v_number = n; 561 list_append(l, li); 562 return OK; 563 } 564 565 /* 566 * Insert typval_T "tv" in list "l" before "item". 567 * If "item" is NULL append at the end. 568 * Return FAIL when out of memory. 569 */ 570 int 571 list_insert_tv(list_T *l, typval_T *tv, listitem_T *item) 572 { 573 listitem_T *ni = listitem_alloc(); 574 575 if (ni == NULL) 576 return FAIL; 577 copy_tv(tv, &ni->li_tv); 578 list_insert(l, ni, item); 579 return OK; 580 } 581 582 void 583 list_insert(list_T *l, listitem_T *ni, listitem_T *item) 584 { 585 if (item == NULL) 586 /* Append new item at end of list. */ 587 list_append(l, ni); 588 else 589 { 590 /* Insert new item before existing item. */ 591 ni->li_prev = item->li_prev; 592 ni->li_next = item; 593 if (item->li_prev == NULL) 594 { 595 l->lv_first = ni; 596 ++l->lv_idx; 597 } 598 else 599 { 600 item->li_prev->li_next = ni; 601 l->lv_idx_item = NULL; 602 } 603 item->li_prev = ni; 604 ++l->lv_len; 605 } 606 } 607 608 /* 609 * Extend "l1" with "l2". 610 * If "bef" is NULL append at the end, otherwise insert before this item. 611 * Returns FAIL when out of memory. 612 */ 613 int 614 list_extend(list_T *l1, list_T *l2, listitem_T *bef) 615 { 616 listitem_T *item; 617 int todo = l2->lv_len; 618 619 /* We also quit the loop when we have inserted the original item count of 620 * the list, avoid a hang when we extend a list with itself. */ 621 for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) 622 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 623 return FAIL; 624 return OK; 625 } 626 627 /* 628 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 629 * Return FAIL when out of memory. 630 */ 631 int 632 list_concat(list_T *l1, list_T *l2, typval_T *tv) 633 { 634 list_T *l; 635 636 if (l1 == NULL || l2 == NULL) 637 return FAIL; 638 639 /* make a copy of the first list. */ 640 l = list_copy(l1, FALSE, 0); 641 if (l == NULL) 642 return FAIL; 643 tv->v_type = VAR_LIST; 644 tv->vval.v_list = l; 645 646 /* append all items from the second list */ 647 return list_extend(l, l2, NULL); 648 } 649 650 /* 651 * Make a copy of list "orig". Shallow if "deep" is FALSE. 652 * The refcount of the new list is set to 1. 653 * See item_copy() for "copyID". 654 * Returns NULL when out of memory. 655 */ 656 list_T * 657 list_copy(list_T *orig, int deep, int copyID) 658 { 659 list_T *copy; 660 listitem_T *item; 661 listitem_T *ni; 662 663 if (orig == NULL) 664 return NULL; 665 666 copy = list_alloc(); 667 if (copy != NULL) 668 { 669 if (copyID != 0) 670 { 671 /* Do this before adding the items, because one of the items may 672 * refer back to this list. */ 673 orig->lv_copyID = copyID; 674 orig->lv_copylist = copy; 675 } 676 for (item = orig->lv_first; item != NULL && !got_int; 677 item = item->li_next) 678 { 679 ni = listitem_alloc(); 680 if (ni == NULL) 681 break; 682 if (deep) 683 { 684 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 685 { 686 vim_free(ni); 687 break; 688 } 689 } 690 else 691 copy_tv(&item->li_tv, &ni->li_tv); 692 list_append(copy, ni); 693 } 694 ++copy->lv_refcount; 695 if (item != NULL) 696 { 697 list_unref(copy); 698 copy = NULL; 699 } 700 } 701 702 return copy; 703 } 704 705 /* 706 * Remove items "item" to "item2" from list "l". 707 * Does not free the listitem or the value! 708 * This used to be called list_remove, but that conflicts with a Sun header 709 * file. 710 */ 711 void 712 vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2) 713 { 714 listitem_T *ip; 715 716 /* notify watchers */ 717 for (ip = item; ip != NULL; ip = ip->li_next) 718 { 719 --l->lv_len; 720 list_fix_watch(l, ip); 721 if (ip == item2) 722 break; 723 } 724 725 if (item2->li_next == NULL) 726 l->lv_last = item->li_prev; 727 else 728 item2->li_next->li_prev = item->li_prev; 729 if (item->li_prev == NULL) 730 l->lv_first = item2->li_next; 731 else 732 item->li_prev->li_next = item2->li_next; 733 l->lv_idx_item = NULL; 734 } 735 736 /* 737 * Return an allocated string with the string representation of a list. 738 * May return NULL. 739 */ 740 char_u * 741 list2string(typval_T *tv, int copyID, int restore_copyID) 742 { 743 garray_T ga; 744 745 if (tv->vval.v_list == NULL) 746 return NULL; 747 ga_init2(&ga, (int)sizeof(char), 80); 748 ga_append(&ga, '['); 749 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", 750 FALSE, restore_copyID, copyID) == FAIL) 751 { 752 vim_free(ga.ga_data); 753 return NULL; 754 } 755 ga_append(&ga, ']'); 756 ga_append(&ga, NUL); 757 return (char_u *)ga.ga_data; 758 } 759 760 typedef struct join_S { 761 char_u *s; 762 char_u *tofree; 763 } join_T; 764 765 static int 766 list_join_inner( 767 garray_T *gap, /* to store the result in */ 768 list_T *l, 769 char_u *sep, 770 int echo_style, 771 int restore_copyID, 772 int copyID, 773 garray_T *join_gap) /* to keep each list item string */ 774 { 775 int i; 776 join_T *p; 777 int len; 778 int sumlen = 0; 779 int first = TRUE; 780 char_u *tofree; 781 char_u numbuf[NUMBUFLEN]; 782 listitem_T *item; 783 char_u *s; 784 785 /* Stringify each item in the list. */ 786 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 787 { 788 s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID, 789 echo_style, restore_copyID, !echo_style); 790 if (s == NULL) 791 return FAIL; 792 793 len = (int)STRLEN(s); 794 sumlen += len; 795 796 (void)ga_grow(join_gap, 1); 797 p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++); 798 if (tofree != NULL || s != numbuf) 799 { 800 p->s = s; 801 p->tofree = tofree; 802 } 803 else 804 { 805 p->s = vim_strnsave(s, len); 806 p->tofree = p->s; 807 } 808 809 line_breakcheck(); 810 if (did_echo_string_emsg) /* recursion error, bail out */ 811 break; 812 } 813 814 /* Allocate result buffer with its total size, avoid re-allocation and 815 * multiple copy operations. Add 2 for a tailing ']' and NUL. */ 816 if (join_gap->ga_len >= 2) 817 sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1); 818 if (ga_grow(gap, sumlen + 2) == FAIL) 819 return FAIL; 820 821 for (i = 0; i < join_gap->ga_len && !got_int; ++i) 822 { 823 if (first) 824 first = FALSE; 825 else 826 ga_concat(gap, sep); 827 p = ((join_T *)join_gap->ga_data) + i; 828 829 if (p->s != NULL) 830 ga_concat(gap, p->s); 831 line_breakcheck(); 832 } 833 834 return OK; 835 } 836 837 /* 838 * Join list "l" into a string in "*gap", using separator "sep". 839 * When "echo_style" is TRUE use String as echoed, otherwise as inside a List. 840 * Return FAIL or OK. 841 */ 842 int 843 list_join( 844 garray_T *gap, 845 list_T *l, 846 char_u *sep, 847 int echo_style, 848 int restore_copyID, 849 int copyID) 850 { 851 garray_T join_ga; 852 int retval; 853 join_T *p; 854 int i; 855 856 if (l->lv_len < 1) 857 return OK; /* nothing to do */ 858 ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len); 859 retval = list_join_inner(gap, l, sep, echo_style, restore_copyID, 860 copyID, &join_ga); 861 862 /* Dispose each item in join_ga. */ 863 if (join_ga.ga_data != NULL) 864 { 865 p = (join_T *)join_ga.ga_data; 866 for (i = 0; i < join_ga.ga_len; ++i) 867 { 868 vim_free(p->tofree); 869 ++p; 870 } 871 ga_clear(&join_ga); 872 } 873 874 return retval; 875 } 876 877 /* 878 * Allocate a variable for a List and fill it from "*arg". 879 * Return OK or FAIL. 880 */ 881 int 882 get_list_tv(char_u **arg, typval_T *rettv, int evaluate) 883 { 884 list_T *l = NULL; 885 typval_T tv; 886 listitem_T *item; 887 888 if (evaluate) 889 { 890 l = list_alloc(); 891 if (l == NULL) 892 return FAIL; 893 } 894 895 *arg = skipwhite(*arg + 1); 896 while (**arg != ']' && **arg != NUL) 897 { 898 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 899 goto failret; 900 if (evaluate) 901 { 902 item = listitem_alloc(); 903 if (item != NULL) 904 { 905 item->li_tv = tv; 906 item->li_tv.v_lock = 0; 907 list_append(l, item); 908 } 909 else 910 clear_tv(&tv); 911 } 912 913 if (**arg == ']') 914 break; 915 if (**arg != ',') 916 { 917 semsg(_("E696: Missing comma in List: %s"), *arg); 918 goto failret; 919 } 920 *arg = skipwhite(*arg + 1); 921 } 922 923 if (**arg != ']') 924 { 925 semsg(_("E697: Missing end of List ']': %s"), *arg); 926 failret: 927 if (evaluate) 928 list_free(l); 929 return FAIL; 930 } 931 932 *arg = skipwhite(*arg + 1); 933 if (evaluate) 934 rettv_list_set(rettv, l); 935 936 return OK; 937 } 938 939 /* 940 * Write "list" of strings to file "fd". 941 */ 942 int 943 write_list(FILE *fd, list_T *list, int binary) 944 { 945 listitem_T *li; 946 int c; 947 int ret = OK; 948 char_u *s; 949 950 for (li = list->lv_first; li != NULL; li = li->li_next) 951 { 952 for (s = tv_get_string(&li->li_tv); *s != NUL; ++s) 953 { 954 if (*s == '\n') 955 c = putc(NUL, fd); 956 else 957 c = putc(*s, fd); 958 if (c == EOF) 959 { 960 ret = FAIL; 961 break; 962 } 963 } 964 if (!binary || li->li_next != NULL) 965 if (putc('\n', fd) == EOF) 966 { 967 ret = FAIL; 968 break; 969 } 970 if (ret == FAIL) 971 { 972 emsg(_(e_write)); 973 break; 974 } 975 } 976 return ret; 977 } 978 979 /* 980 * Initialize a static list with 10 items. 981 */ 982 void 983 init_static_list(staticList10_T *sl) 984 { 985 list_T *l = &sl->sl_list; 986 int i; 987 988 memset(sl, 0, sizeof(staticList10_T)); 989 l->lv_first = &sl->sl_items[0]; 990 l->lv_last = &sl->sl_items[9]; 991 l->lv_refcount = DO_NOT_FREE_CNT; 992 l->lv_lock = VAR_FIXED; 993 sl->sl_list.lv_len = 10; 994 995 for (i = 0; i < 10; ++i) 996 { 997 listitem_T *li = &sl->sl_items[i]; 998 999 if (i == 0) 1000 li->li_prev = NULL; 1001 else 1002 li->li_prev = li - 1; 1003 if (i == 9) 1004 li->li_next = NULL; 1005 else 1006 li->li_next = li + 1; 1007 } 1008 } 1009 1010 #endif /* defined(FEAT_EVAL) */ 1011