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