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 = ALLOC_CLEAR_ONE(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(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(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. Increments the reference count. 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 ALLOC_ONE(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 * "join()" function 879 */ 880 void 881 f_join(typval_T *argvars, typval_T *rettv) 882 { 883 garray_T ga; 884 char_u *sep; 885 886 if (argvars[0].v_type != VAR_LIST) 887 { 888 emsg(_(e_listreq)); 889 return; 890 } 891 if (argvars[0].vval.v_list == NULL) 892 return; 893 if (argvars[1].v_type == VAR_UNKNOWN) 894 sep = (char_u *)" "; 895 else 896 sep = tv_get_string_chk(&argvars[1]); 897 898 rettv->v_type = VAR_STRING; 899 900 if (sep != NULL) 901 { 902 ga_init2(&ga, (int)sizeof(char), 80); 903 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, FALSE, 0); 904 ga_append(&ga, NUL); 905 rettv->vval.v_string = (char_u *)ga.ga_data; 906 } 907 else 908 rettv->vval.v_string = NULL; 909 } 910 911 /* 912 * Allocate a variable for a List and fill it from "*arg". 913 * Return OK or FAIL. 914 */ 915 int 916 get_list_tv(char_u **arg, typval_T *rettv, int evaluate) 917 { 918 list_T *l = NULL; 919 typval_T tv; 920 listitem_T *item; 921 922 if (evaluate) 923 { 924 l = list_alloc(); 925 if (l == NULL) 926 return FAIL; 927 } 928 929 *arg = skipwhite(*arg + 1); 930 while (**arg != ']' && **arg != NUL) 931 { 932 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 933 goto failret; 934 if (evaluate) 935 { 936 item = listitem_alloc(); 937 if (item != NULL) 938 { 939 item->li_tv = tv; 940 item->li_tv.v_lock = 0; 941 list_append(l, item); 942 } 943 else 944 clear_tv(&tv); 945 } 946 947 if (**arg == ']') 948 break; 949 if (**arg != ',') 950 { 951 semsg(_("E696: Missing comma in List: %s"), *arg); 952 goto failret; 953 } 954 *arg = skipwhite(*arg + 1); 955 } 956 957 if (**arg != ']') 958 { 959 semsg(_("E697: Missing end of List ']': %s"), *arg); 960 failret: 961 if (evaluate) 962 list_free(l); 963 return FAIL; 964 } 965 966 *arg = skipwhite(*arg + 1); 967 if (evaluate) 968 rettv_list_set(rettv, l); 969 970 return OK; 971 } 972 973 /* 974 * Write "list" of strings to file "fd". 975 */ 976 int 977 write_list(FILE *fd, list_T *list, int binary) 978 { 979 listitem_T *li; 980 int c; 981 int ret = OK; 982 char_u *s; 983 984 for (li = list->lv_first; li != NULL; li = li->li_next) 985 { 986 for (s = tv_get_string(&li->li_tv); *s != NUL; ++s) 987 { 988 if (*s == '\n') 989 c = putc(NUL, fd); 990 else 991 c = putc(*s, fd); 992 if (c == EOF) 993 { 994 ret = FAIL; 995 break; 996 } 997 } 998 if (!binary || li->li_next != NULL) 999 if (putc('\n', fd) == EOF) 1000 { 1001 ret = FAIL; 1002 break; 1003 } 1004 if (ret == FAIL) 1005 { 1006 emsg(_(e_write)); 1007 break; 1008 } 1009 } 1010 return ret; 1011 } 1012 1013 /* 1014 * Initialize a static list with 10 items. 1015 */ 1016 void 1017 init_static_list(staticList10_T *sl) 1018 { 1019 list_T *l = &sl->sl_list; 1020 int i; 1021 1022 memset(sl, 0, sizeof(staticList10_T)); 1023 l->lv_first = &sl->sl_items[0]; 1024 l->lv_last = &sl->sl_items[9]; 1025 l->lv_refcount = DO_NOT_FREE_CNT; 1026 l->lv_lock = VAR_FIXED; 1027 sl->sl_list.lv_len = 10; 1028 1029 for (i = 0; i < 10; ++i) 1030 { 1031 listitem_T *li = &sl->sl_items[i]; 1032 1033 if (i == 0) 1034 li->li_prev = NULL; 1035 else 1036 li->li_prev = li - 1; 1037 if (i == 9) 1038 li->li_next = NULL; 1039 else 1040 li->li_next = li + 1; 1041 } 1042 } 1043 1044 /* 1045 * "list2str()" function 1046 */ 1047 void 1048 f_list2str(typval_T *argvars, typval_T *rettv) 1049 { 1050 list_T *l; 1051 listitem_T *li; 1052 garray_T ga; 1053 int utf8 = FALSE; 1054 1055 rettv->v_type = VAR_STRING; 1056 rettv->vval.v_string = NULL; 1057 if (argvars[0].v_type != VAR_LIST) 1058 { 1059 emsg(_(e_invarg)); 1060 return; 1061 } 1062 1063 l = argvars[0].vval.v_list; 1064 if (l == NULL) 1065 return; // empty list results in empty string 1066 1067 if (argvars[1].v_type != VAR_UNKNOWN) 1068 utf8 = (int)tv_get_number_chk(&argvars[1], NULL); 1069 1070 ga_init2(&ga, 1, 80); 1071 if (has_mbyte || utf8) 1072 { 1073 char_u buf[MB_MAXBYTES + 1]; 1074 int (*char2bytes)(int, char_u *); 1075 1076 if (utf8 || enc_utf8) 1077 char2bytes = utf_char2bytes; 1078 else 1079 char2bytes = mb_char2bytes; 1080 1081 for (li = l->lv_first; li != NULL; li = li->li_next) 1082 { 1083 buf[(*char2bytes)(tv_get_number(&li->li_tv), buf)] = NUL; 1084 ga_concat(&ga, buf); 1085 } 1086 ga_append(&ga, NUL); 1087 } 1088 else if (ga_grow(&ga, list_len(l) + 1) == OK) 1089 { 1090 for (li = l->lv_first; li != NULL; li = li->li_next) 1091 ga_append(&ga, tv_get_number(&li->li_tv)); 1092 ga_append(&ga, NUL); 1093 } 1094 1095 rettv->v_type = VAR_STRING; 1096 rettv->vval.v_string = ga.ga_data; 1097 } 1098 1099 void 1100 list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg) 1101 { 1102 list_T *l; 1103 listitem_T *item, *item2; 1104 listitem_T *li; 1105 int error = FALSE; 1106 int idx; 1107 1108 if ((l = argvars[0].vval.v_list) == NULL 1109 || var_check_lock(l->lv_lock, arg_errmsg, TRUE)) 1110 return; 1111 1112 idx = (long)tv_get_number_chk(&argvars[1], &error); 1113 if (error) 1114 ; // type error: do nothing, errmsg already given 1115 else if ((item = list_find(l, idx)) == NULL) 1116 semsg(_(e_listidx), idx); 1117 else 1118 { 1119 if (argvars[2].v_type == VAR_UNKNOWN) 1120 { 1121 /* Remove one item, return its value. */ 1122 vimlist_remove(l, item, item); 1123 *rettv = item->li_tv; 1124 vim_free(item); 1125 } 1126 else 1127 { 1128 // Remove range of items, return list with values. 1129 int end = (long)tv_get_number_chk(&argvars[2], &error); 1130 1131 if (error) 1132 ; // type error: do nothing 1133 else if ((item2 = list_find(l, end)) == NULL) 1134 semsg(_(e_listidx), end); 1135 else 1136 { 1137 int cnt = 0; 1138 1139 for (li = item; li != NULL; li = li->li_next) 1140 { 1141 ++cnt; 1142 if (li == item2) 1143 break; 1144 } 1145 if (li == NULL) /* didn't find "item2" after "item" */ 1146 emsg(_(e_invrange)); 1147 else 1148 { 1149 vimlist_remove(l, item, item2); 1150 if (rettv_list_alloc(rettv) == OK) 1151 { 1152 l = rettv->vval.v_list; 1153 l->lv_first = item; 1154 l->lv_last = item2; 1155 item->li_prev = NULL; 1156 item2->li_next = NULL; 1157 l->lv_len = cnt; 1158 } 1159 } 1160 } 1161 } 1162 } 1163 } 1164 1165 static int item_compare(const void *s1, const void *s2); 1166 static int item_compare2(const void *s1, const void *s2); 1167 1168 /* struct used in the array that's given to qsort() */ 1169 typedef struct 1170 { 1171 listitem_T *item; 1172 int idx; 1173 } sortItem_T; 1174 1175 /* struct storing information about current sort */ 1176 typedef struct 1177 { 1178 int item_compare_ic; 1179 int item_compare_numeric; 1180 int item_compare_numbers; 1181 #ifdef FEAT_FLOAT 1182 int item_compare_float; 1183 #endif 1184 char_u *item_compare_func; 1185 partial_T *item_compare_partial; 1186 dict_T *item_compare_selfdict; 1187 int item_compare_func_err; 1188 int item_compare_keep_zero; 1189 } sortinfo_T; 1190 static sortinfo_T *sortinfo = NULL; 1191 #define ITEM_COMPARE_FAIL 999 1192 1193 /* 1194 * Compare functions for f_sort() and f_uniq() below. 1195 */ 1196 static int 1197 item_compare(const void *s1, const void *s2) 1198 { 1199 sortItem_T *si1, *si2; 1200 typval_T *tv1, *tv2; 1201 char_u *p1, *p2; 1202 char_u *tofree1 = NULL, *tofree2 = NULL; 1203 int res; 1204 char_u numbuf1[NUMBUFLEN]; 1205 char_u numbuf2[NUMBUFLEN]; 1206 1207 si1 = (sortItem_T *)s1; 1208 si2 = (sortItem_T *)s2; 1209 tv1 = &si1->item->li_tv; 1210 tv2 = &si2->item->li_tv; 1211 1212 if (sortinfo->item_compare_numbers) 1213 { 1214 varnumber_T v1 = tv_get_number(tv1); 1215 varnumber_T v2 = tv_get_number(tv2); 1216 1217 return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; 1218 } 1219 1220 #ifdef FEAT_FLOAT 1221 if (sortinfo->item_compare_float) 1222 { 1223 float_T v1 = tv_get_float(tv1); 1224 float_T v2 = tv_get_float(tv2); 1225 1226 return v1 == v2 ? 0 : v1 > v2 ? 1 : -1; 1227 } 1228 #endif 1229 1230 /* tv2string() puts quotes around a string and allocates memory. Don't do 1231 * that for string variables. Use a single quote when comparing with a 1232 * non-string to do what the docs promise. */ 1233 if (tv1->v_type == VAR_STRING) 1234 { 1235 if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric) 1236 p1 = (char_u *)"'"; 1237 else 1238 p1 = tv1->vval.v_string; 1239 } 1240 else 1241 p1 = tv2string(tv1, &tofree1, numbuf1, 0); 1242 if (tv2->v_type == VAR_STRING) 1243 { 1244 if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric) 1245 p2 = (char_u *)"'"; 1246 else 1247 p2 = tv2->vval.v_string; 1248 } 1249 else 1250 p2 = tv2string(tv2, &tofree2, numbuf2, 0); 1251 if (p1 == NULL) 1252 p1 = (char_u *)""; 1253 if (p2 == NULL) 1254 p2 = (char_u *)""; 1255 if (!sortinfo->item_compare_numeric) 1256 { 1257 if (sortinfo->item_compare_ic) 1258 res = STRICMP(p1, p2); 1259 else 1260 res = STRCMP(p1, p2); 1261 } 1262 else 1263 { 1264 double n1, n2; 1265 n1 = strtod((char *)p1, (char **)&p1); 1266 n2 = strtod((char *)p2, (char **)&p2); 1267 res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1; 1268 } 1269 1270 /* When the result would be zero, compare the item indexes. Makes the 1271 * sort stable. */ 1272 if (res == 0 && !sortinfo->item_compare_keep_zero) 1273 res = si1->idx > si2->idx ? 1 : -1; 1274 1275 vim_free(tofree1); 1276 vim_free(tofree2); 1277 return res; 1278 } 1279 1280 static int 1281 item_compare2(const void *s1, const void *s2) 1282 { 1283 sortItem_T *si1, *si2; 1284 int res; 1285 typval_T rettv; 1286 typval_T argv[3]; 1287 char_u *func_name; 1288 partial_T *partial = sortinfo->item_compare_partial; 1289 funcexe_T funcexe; 1290 1291 /* shortcut after failure in previous call; compare all items equal */ 1292 if (sortinfo->item_compare_func_err) 1293 return 0; 1294 1295 si1 = (sortItem_T *)s1; 1296 si2 = (sortItem_T *)s2; 1297 1298 if (partial == NULL) 1299 func_name = sortinfo->item_compare_func; 1300 else 1301 func_name = partial_name(partial); 1302 1303 /* Copy the values. This is needed to be able to set v_lock to VAR_FIXED 1304 * in the copy without changing the original list items. */ 1305 copy_tv(&si1->item->li_tv, &argv[0]); 1306 copy_tv(&si2->item->li_tv, &argv[1]); 1307 1308 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 1309 vim_memset(&funcexe, 0, sizeof(funcexe)); 1310 funcexe.evaluate = TRUE; 1311 funcexe.partial = partial; 1312 funcexe.selfdict = sortinfo->item_compare_selfdict; 1313 res = call_func(func_name, -1, &rettv, 2, argv, &funcexe); 1314 clear_tv(&argv[0]); 1315 clear_tv(&argv[1]); 1316 1317 if (res == FAIL) 1318 res = ITEM_COMPARE_FAIL; 1319 else 1320 res = (int)tv_get_number_chk(&rettv, &sortinfo->item_compare_func_err); 1321 if (sortinfo->item_compare_func_err) 1322 res = ITEM_COMPARE_FAIL; /* return value has wrong type */ 1323 clear_tv(&rettv); 1324 1325 /* When the result would be zero, compare the pointers themselves. Makes 1326 * the sort stable. */ 1327 if (res == 0 && !sortinfo->item_compare_keep_zero) 1328 res = si1->idx > si2->idx ? 1 : -1; 1329 1330 return res; 1331 } 1332 1333 /* 1334 * "sort()" or "uniq()" function 1335 */ 1336 static void 1337 do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort) 1338 { 1339 list_T *l; 1340 listitem_T *li; 1341 sortItem_T *ptrs; 1342 sortinfo_T *old_sortinfo; 1343 sortinfo_T info; 1344 long len; 1345 long i; 1346 1347 /* Pointer to current info struct used in compare function. Save and 1348 * restore the current one for nested calls. */ 1349 old_sortinfo = sortinfo; 1350 sortinfo = &info; 1351 1352 if (argvars[0].v_type != VAR_LIST) 1353 semsg(_(e_listarg), sort ? "sort()" : "uniq()"); 1354 else 1355 { 1356 l = argvars[0].vval.v_list; 1357 if (l == NULL || var_check_lock(l->lv_lock, 1358 (char_u *)(sort ? N_("sort() argument") : N_("uniq() argument")), 1359 TRUE)) 1360 goto theend; 1361 rettv_list_set(rettv, l); 1362 1363 len = list_len(l); 1364 if (len <= 1) 1365 goto theend; /* short list sorts pretty quickly */ 1366 1367 info.item_compare_ic = FALSE; 1368 info.item_compare_numeric = FALSE; 1369 info.item_compare_numbers = FALSE; 1370 #ifdef FEAT_FLOAT 1371 info.item_compare_float = FALSE; 1372 #endif 1373 info.item_compare_func = NULL; 1374 info.item_compare_partial = NULL; 1375 info.item_compare_selfdict = NULL; 1376 if (argvars[1].v_type != VAR_UNKNOWN) 1377 { 1378 /* optional second argument: {func} */ 1379 if (argvars[1].v_type == VAR_FUNC) 1380 info.item_compare_func = argvars[1].vval.v_string; 1381 else if (argvars[1].v_type == VAR_PARTIAL) 1382 info.item_compare_partial = argvars[1].vval.v_partial; 1383 else 1384 { 1385 int error = FALSE; 1386 1387 i = (long)tv_get_number_chk(&argvars[1], &error); 1388 if (error) 1389 goto theend; /* type error; errmsg already given */ 1390 if (i == 1) 1391 info.item_compare_ic = TRUE; 1392 else if (argvars[1].v_type != VAR_NUMBER) 1393 info.item_compare_func = tv_get_string(&argvars[1]); 1394 else if (i != 0) 1395 { 1396 emsg(_(e_invarg)); 1397 goto theend; 1398 } 1399 if (info.item_compare_func != NULL) 1400 { 1401 if (*info.item_compare_func == NUL) 1402 { 1403 /* empty string means default sort */ 1404 info.item_compare_func = NULL; 1405 } 1406 else if (STRCMP(info.item_compare_func, "n") == 0) 1407 { 1408 info.item_compare_func = NULL; 1409 info.item_compare_numeric = TRUE; 1410 } 1411 else if (STRCMP(info.item_compare_func, "N") == 0) 1412 { 1413 info.item_compare_func = NULL; 1414 info.item_compare_numbers = TRUE; 1415 } 1416 #ifdef FEAT_FLOAT 1417 else if (STRCMP(info.item_compare_func, "f") == 0) 1418 { 1419 info.item_compare_func = NULL; 1420 info.item_compare_float = TRUE; 1421 } 1422 #endif 1423 else if (STRCMP(info.item_compare_func, "i") == 0) 1424 { 1425 info.item_compare_func = NULL; 1426 info.item_compare_ic = TRUE; 1427 } 1428 } 1429 } 1430 1431 if (argvars[2].v_type != VAR_UNKNOWN) 1432 { 1433 /* optional third argument: {dict} */ 1434 if (argvars[2].v_type != VAR_DICT) 1435 { 1436 emsg(_(e_dictreq)); 1437 goto theend; 1438 } 1439 info.item_compare_selfdict = argvars[2].vval.v_dict; 1440 } 1441 } 1442 1443 /* Make an array with each entry pointing to an item in the List. */ 1444 ptrs = ALLOC_MULT(sortItem_T, len); 1445 if (ptrs == NULL) 1446 goto theend; 1447 1448 i = 0; 1449 if (sort) 1450 { 1451 /* sort(): ptrs will be the list to sort */ 1452 for (li = l->lv_first; li != NULL; li = li->li_next) 1453 { 1454 ptrs[i].item = li; 1455 ptrs[i].idx = i; 1456 ++i; 1457 } 1458 1459 info.item_compare_func_err = FALSE; 1460 info.item_compare_keep_zero = FALSE; 1461 /* test the compare function */ 1462 if ((info.item_compare_func != NULL 1463 || info.item_compare_partial != NULL) 1464 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 1465 == ITEM_COMPARE_FAIL) 1466 emsg(_("E702: Sort compare function failed")); 1467 else 1468 { 1469 /* Sort the array with item pointers. */ 1470 qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T), 1471 info.item_compare_func == NULL 1472 && info.item_compare_partial == NULL 1473 ? item_compare : item_compare2); 1474 1475 if (!info.item_compare_func_err) 1476 { 1477 /* Clear the List and append the items in sorted order. */ 1478 l->lv_first = l->lv_last = l->lv_idx_item = NULL; 1479 l->lv_len = 0; 1480 for (i = 0; i < len; ++i) 1481 list_append(l, ptrs[i].item); 1482 } 1483 } 1484 } 1485 else 1486 { 1487 int (*item_compare_func_ptr)(const void *, const void *); 1488 1489 /* f_uniq(): ptrs will be a stack of items to remove */ 1490 info.item_compare_func_err = FALSE; 1491 info.item_compare_keep_zero = TRUE; 1492 item_compare_func_ptr = info.item_compare_func != NULL 1493 || info.item_compare_partial != NULL 1494 ? item_compare2 : item_compare; 1495 1496 for (li = l->lv_first; li != NULL && li->li_next != NULL; 1497 li = li->li_next) 1498 { 1499 if (item_compare_func_ptr((void *)&li, (void *)&li->li_next) 1500 == 0) 1501 ptrs[i++].item = li; 1502 if (info.item_compare_func_err) 1503 { 1504 emsg(_("E882: Uniq compare function failed")); 1505 break; 1506 } 1507 } 1508 1509 if (!info.item_compare_func_err) 1510 { 1511 while (--i >= 0) 1512 { 1513 li = ptrs[i].item->li_next; 1514 ptrs[i].item->li_next = li->li_next; 1515 if (li->li_next != NULL) 1516 li->li_next->li_prev = ptrs[i].item; 1517 else 1518 l->lv_last = ptrs[i].item; 1519 list_fix_watch(l, li); 1520 listitem_free(li); 1521 l->lv_len--; 1522 } 1523 } 1524 } 1525 1526 vim_free(ptrs); 1527 } 1528 theend: 1529 sortinfo = old_sortinfo; 1530 } 1531 1532 /* 1533 * "sort({list})" function 1534 */ 1535 void 1536 f_sort(typval_T *argvars, typval_T *rettv) 1537 { 1538 do_sort_uniq(argvars, rettv, TRUE); 1539 } 1540 1541 /* 1542 * "uniq({list})" function 1543 */ 1544 void 1545 f_uniq(typval_T *argvars, typval_T *rettv) 1546 { 1547 do_sort_uniq(argvars, rettv, FALSE); 1548 } 1549 1550 #endif /* defined(FEAT_EVAL) */ 1551