annotate src/list.c @ 32816:939396a5711c v9.0.1722

patch 9.0.1722: wrong error messages when passing wrong types to count() Commit: https://github.com/vim/vim/commit/4f389e7c0fe7dfeccfa512a72fa36f9028d57159 Author: zeertzjq <zeertzjq@outlook.com> Date: Thu Aug 17 22:10:40 2023 +0200 patch 9.0.1722: wrong error messages when passing wrong types to count() Problem: wrong error messages when passing wrong types to count() Solution: fix it This fixes two problems: 1. When passing wrong type to {ic} argument of count(), two error messages are given, the second of which is misleading. 2. When passing wrong type to {comp} argument of count(), the error message doesn't mention that {comp} may be a String. closes: #12825 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: zeertzjq <zeertzjq@outlook.com>
author Christian Brabandt <cb@256bit.org>
date Thu, 17 Aug 2023 22:15:03 +0200
parents 695b50472e85
children 705d0e1329a5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32670
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1 /* vi:set ts=8 sts=4 sw=4 noet:
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2 *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3 * VIM - Vi IMproved by Bram Moolenaar
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
4 *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
5 * Do ":help uganda" in Vim to read copying and usage conditions.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
6 * Do ":help credits" in Vim to see a list of people who contributed.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
7 * See README.txt for an overview of the Vim source code.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
8 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
9
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
10 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
11 * list.c: List support and container (List, Dict, Blob) functions.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
12 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
13
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
14 #include "vim.h"
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
15
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
16 #if defined(FEAT_EVAL) || defined(PROTO)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
17
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
18 // List heads for garbage collection.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
19 static list_T *first_list = NULL; // list of all lists
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
20
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
21 #define FOR_ALL_WATCHERS(l, lw) \
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
22 for ((lw) = (l)->lv_watch; (lw) != NULL; (lw) = (lw)->lw_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
23
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
24 static void list_free_item(list_T *l, listitem_T *item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
25
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
26 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
27 * Add a watcher to a list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
28 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
29 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
30 list_add_watch(list_T *l, listwatch_T *lw)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
31 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
32 lw->lw_next = l->lv_watch;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
33 l->lv_watch = lw;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
34 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
35
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
36 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
37 * Remove a watcher from a list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
38 * No warning when it isn't found...
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
39 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
40 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
41 list_rem_watch(list_T *l, listwatch_T *lwrem)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
42 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
43 listwatch_T *lw, **lwp;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
44
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
45 lwp = &l->lv_watch;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
46 FOR_ALL_WATCHERS(l, lw)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
47 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
48 if (lw == lwrem)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
49 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
50 *lwp = lw->lw_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
51 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
52 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
53 lwp = &lw->lw_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
54 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
55 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
56
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
57 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
58 * Just before removing an item from a list: advance watchers to the next
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
59 * item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
60 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
61 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
62 list_fix_watch(list_T *l, listitem_T *item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
63 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
64 listwatch_T *lw;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
65
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
66 FOR_ALL_WATCHERS(l, lw)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
67 if (lw->lw_item == item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
68 lw->lw_item = item->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
69 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
70
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
71 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
72 list_init(list_T *l)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
73 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
74 // Prepend the list to the list of lists for garbage collection.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
75 if (first_list != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
76 first_list->lv_used_prev = l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
77 l->lv_used_prev = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
78 l->lv_used_next = first_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
79 first_list = l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
80 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
81
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
82 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
83 * Allocate an empty header for a list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
84 * Caller should take care of the reference count.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
85 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
86 list_T *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
87 list_alloc(void)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
88 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
89 list_T *l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
90
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
91 l = ALLOC_CLEAR_ONE(list_T);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
92 if (l != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
93 list_init(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
94 return l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
95 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
96
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
97 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
98 * list_alloc() with an ID for alloc_fail().
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
99 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
100 list_T *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
101 list_alloc_id(alloc_id_T id UNUSED)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
102 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
103 #ifdef FEAT_EVAL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
104 if (alloc_fail_id == id && alloc_does_fail(sizeof(list_T)))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
105 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
106 #endif
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
107 return (list_alloc());
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
108 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
109
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
110 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
111 * Allocate space for a list, plus "count" items.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
112 * This uses one allocation for efficiency.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
113 * The reference count is not set.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
114 * Next list_set_item() must be called for each item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
115 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
116 list_T *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
117 list_alloc_with_items(int count)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
118 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
119 list_T *l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
120
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
121 l = (list_T *)alloc_clear(sizeof(list_T) + count * sizeof(listitem_T));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
122 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
123 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
124
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
125 list_init(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
126
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
127 if (count <= 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
128 return l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
129
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
130 listitem_T *li = (listitem_T *)(l + 1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
131 int i;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
132
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
133 l->lv_len = count;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
134 l->lv_with_items = count;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
135 l->lv_first = li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
136 l->lv_u.mat.lv_last = li + count - 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
137 for (i = 0; i < count; ++i)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
138 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
139 if (i == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
140 li->li_prev = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
141 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
142 li->li_prev = li - 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
143 if (i == count - 1)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
144 li->li_next = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
145 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
146 li->li_next = li + 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
147 ++li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
148 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
149
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
150 return l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
151 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
152
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
153 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
154 * Set item "idx" for a list previously allocated with list_alloc_with_items().
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
155 * The contents of "tv" is moved into the list item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
156 * Each item must be set exactly once.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
157 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
158 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
159 list_set_item(list_T *l, int idx, typval_T *tv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
160 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
161 listitem_T *li = (listitem_T *)(l + 1) + idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
162
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
163 li->li_tv = *tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
164 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
165
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
166 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
167 * Allocate an empty list for a return value, with reference count set.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
168 * Returns OK or FAIL.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
169 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
170 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
171 rettv_list_alloc(typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
172 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
173 list_T *l = list_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
174
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
175 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
176 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
177
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
178 rettv->v_lock = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
179 rettv_list_set(rettv, l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
180 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
181 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
182
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
183 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
184 * Same as rettv_list_alloc() but uses an allocation id for testing.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
185 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
186 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
187 rettv_list_alloc_id(typval_T *rettv, alloc_id_T id UNUSED)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
188 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
189 #ifdef FEAT_EVAL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
190 if (alloc_fail_id == id && alloc_does_fail(sizeof(list_T)))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
191 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
192 #endif
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
193 return rettv_list_alloc(rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
194 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
195
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
196
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
197 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
198 * Set a list as the return value. Increments the reference count.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
199 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
200 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
201 rettv_list_set(typval_T *rettv, list_T *l)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
202 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
203 rettv->v_type = VAR_LIST;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
204 rettv->vval.v_list = l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
205 if (l != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
206 ++l->lv_refcount;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
207 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
208
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
209 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
210 * Unreference a list: decrement the reference count and free it when it
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
211 * becomes zero.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
212 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
213 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
214 list_unref(list_T *l)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
215 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
216 if (l != NULL && --l->lv_refcount <= 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
217 list_free(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
218 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
219
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
220 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
221 * Free a list, including all non-container items it points to.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
222 * Ignores the reference count.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
223 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
224 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
225 list_free_contents(list_T *l)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
226 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
227 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
228
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
229 if (l->lv_first != &range_list_item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
230 for (item = l->lv_first; item != NULL; item = l->lv_first)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
231 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
232 // Remove the item before deleting it.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
233 l->lv_first = item->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
234 clear_tv(&item->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
235 list_free_item(l, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
236 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
237 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
238
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
239 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
240 * Go through the list of lists and free items without the copyID.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
241 * But don't free a list that has a watcher (used in a for loop), these
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
242 * are not referenced anywhere.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
243 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
244 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
245 list_free_nonref(int copyID)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
246 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
247 list_T *ll;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
248 int did_free = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
249
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
250 for (ll = first_list; ll != NULL; ll = ll->lv_used_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
251 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
252 && ll->lv_watch == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
253 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
254 // Free the List and ordinary items it contains, but don't recurse
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
255 // into Lists and Dictionaries, they will be in the list of dicts
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
256 // or list of lists.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
257 list_free_contents(ll);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
258 did_free = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
259 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
260 return did_free;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
261 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
262
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
263 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
264 list_free_list(list_T *l)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
265 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
266 // Remove the list from the list of lists for garbage collection.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
267 if (l->lv_used_prev == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
268 first_list = l->lv_used_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
269 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
270 l->lv_used_prev->lv_used_next = l->lv_used_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
271 if (l->lv_used_next != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
272 l->lv_used_next->lv_used_prev = l->lv_used_prev;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
273
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
274 free_type(l->lv_type);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
275 vim_free(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
276 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
277
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
278 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
279 list_free_items(int copyID)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
280 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
281 list_T *ll, *ll_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
282
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
283 for (ll = first_list; ll != NULL; ll = ll_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
284 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
285 ll_next = ll->lv_used_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
286 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
287 && ll->lv_watch == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
288 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
289 // Free the List and ordinary items it contains, but don't recurse
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
290 // into Lists and Dictionaries, they will be in the list of dicts
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
291 // or list of lists.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
292 list_free_list(ll);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
293 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
294 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
295 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
296
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
297 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
298 list_free(list_T *l)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
299 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
300 if (in_free_unref_items)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
301 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
302
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
303 list_free_contents(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
304 list_free_list(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
305 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
306
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
307 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
308 * Allocate a list item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
309 * It is not initialized, don't forget to set v_lock.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
310 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
311 listitem_T *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
312 listitem_alloc(void)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
313 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
314 return ALLOC_ONE(listitem_T);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
315 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
316
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
317 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
318 * Free a list item, unless it was allocated together with the list itself.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
319 * Does not clear the value. Does not notify watchers.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
320 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
321 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
322 list_free_item(list_T *l, listitem_T *item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
323 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
324 if (l->lv_with_items == 0 || item < (listitem_T *)l
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
325 || item >= (listitem_T *)(l + 1) + l->lv_with_items)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
326 vim_free(item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
327 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
328
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
329 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
330 * Free a list item, unless it was allocated together with the list itself.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
331 * Also clears the value. Does not notify watchers.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
332 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
333 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
334 listitem_free(list_T *l, listitem_T *item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
335 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
336 clear_tv(&item->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
337 list_free_item(l, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
338 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
339
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
340 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
341 * Remove a list item from a List and free it. Also clears the value.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
342 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
343 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
344 listitem_remove(list_T *l, listitem_T *item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
345 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
346 vimlist_remove(l, item, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
347 listitem_free(l, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
348 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
349
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
350 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
351 * Get the number of items in a list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
352 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
353 long
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
354 list_len(list_T *l)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
355 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
356 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
357 return 0L;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
358 return l->lv_len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
359 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
360
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
361 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
362 * Return TRUE when two lists have exactly the same values.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
363 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
364 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
365 list_equal(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
366 list_T *l1,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
367 list_T *l2,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
368 int ic, // ignore case for strings
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
369 int recursive) // TRUE when used recursively
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
370 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
371 listitem_T *item1, *item2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
372
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
373 if (l1 == l2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
374 return TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
375 if (list_len(l1) != list_len(l2))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
376 return FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
377 if (list_len(l1) == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
378 // empty and NULL list are considered equal
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
379 return TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
380 if (l1 == NULL || l2 == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
381 return FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
382
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
383 CHECK_LIST_MATERIALIZE(l1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
384 CHECK_LIST_MATERIALIZE(l2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
385
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
386 for (item1 = l1->lv_first, item2 = l2->lv_first;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
387 item1 != NULL && item2 != NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
388 item1 = item1->li_next, item2 = item2->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
389 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
390 return FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
391 return item1 == NULL && item2 == NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
392 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
393
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
394 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
395 * Locate item with index "n" in list "l" and return it.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
396 * A negative index is counted from the end; -1 is the last item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
397 * Returns NULL when "n" is out of range.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
398 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
399 listitem_T *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
400 list_find(list_T *l, long n)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
401 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
402 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
403 long idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
404
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
405 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
406 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
407
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
408 // Negative index is relative to the end.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
409 if (n < 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
410 n = l->lv_len + n;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
411
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
412 // Check for index out of range.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
413 if (n < 0 || n >= l->lv_len)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
414 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
415
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
416 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
417
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
418 // When there is a cached index may start search from there.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
419 if (l->lv_u.mat.lv_idx_item != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
420 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
421 if (n < l->lv_u.mat.lv_idx / 2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
422 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
423 // closest to the start of the list
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
424 item = l->lv_first;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
425 idx = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
426 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
427 else if (n > (l->lv_u.mat.lv_idx + l->lv_len) / 2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
428 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
429 // closest to the end of the list
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
430 item = l->lv_u.mat.lv_last;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
431 idx = l->lv_len - 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
432 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
433 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
434 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
435 // closest to the cached index
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
436 item = l->lv_u.mat.lv_idx_item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
437 idx = l->lv_u.mat.lv_idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
438 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
439 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
440 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
441 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
442 if (n < l->lv_len / 2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
443 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
444 // closest to the start of the list
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
445 item = l->lv_first;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
446 idx = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
447 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
448 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
449 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
450 // closest to the end of the list
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
451 item = l->lv_u.mat.lv_last;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
452 idx = l->lv_len - 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
453 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
454 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
455
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
456 while (n > idx)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
457 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
458 // search forward
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
459 item = item->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
460 ++idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
461 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
462 while (n < idx)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
463 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
464 // search backward
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
465 item = item->li_prev;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
466 --idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
467 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
468
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
469 // cache the used index
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
470 l->lv_u.mat.lv_idx = idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
471 l->lv_u.mat.lv_idx_item = item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
472
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
473 return item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
474 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
475
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
476 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
477 * Get list item "l[idx]" as a number.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
478 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
479 long
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
480 list_find_nr(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
481 list_T *l,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
482 long idx,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
483 int *errorp) // set to TRUE when something wrong
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
484 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
485 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
486
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
487 if (l != NULL && l->lv_first == &range_list_item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
488 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
489 long n = idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
490
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
491 // not materialized range() list: compute the value.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
492 // Negative index is relative to the end.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
493 if (n < 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
494 n = l->lv_len + n;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
495
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
496 // Check for index out of range.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
497 if (n < 0 || n >= l->lv_len)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
498 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
499 if (errorp != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
500 *errorp = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
501 return -1L;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
502 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
503
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
504 return l->lv_u.nonmat.lv_start + n * l->lv_u.nonmat.lv_stride;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
505 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
506
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
507 li = list_find(l, idx);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
508 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
509 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
510 if (errorp != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
511 *errorp = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
512 return -1L;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
513 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
514 return (long)tv_get_number_chk(&li->li_tv, errorp);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
515 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
516
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
517 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
518 * Get list item "l[idx - 1]" as a string. Returns NULL for failure.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
519 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
520 char_u *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
521 list_find_str(list_T *l, long idx)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
522 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
523 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
524
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
525 li = list_find(l, idx - 1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
526 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
527 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
528 semsg(_(e_list_index_out_of_range_nr), idx);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
529 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
530 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
531 return tv_get_string(&li->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
532 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
533
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
534 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
535 * Like list_find() but when a negative index is used that is not found use
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
536 * zero and set "idx" to zero. Used for first index of a range.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
537 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
538 listitem_T *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
539 list_find_index(list_T *l, long *idx)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
540 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
541 listitem_T *li = list_find(l, *idx);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
542
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
543 if (li != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
544 return li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
545
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
546 if (*idx < 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
547 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
548 *idx = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
549 li = list_find(l, *idx);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
550 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
551 return li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
552 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
553
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
554 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
555 * Locate "item" list "l" and return its index.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
556 * Returns -1 when "item" is not in the list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
557 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
558 long
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
559 list_idx_of_item(list_T *l, listitem_T *item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
560 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
561 long idx = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
562 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
563
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
564 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
565 return -1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
566 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
567 idx = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
568 for (li = l->lv_first; li != NULL && li != item; li = li->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
569 ++idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
570 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
571 return -1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
572 return idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
573 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
574
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
575 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
576 * Append item "item" to the end of list "l".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
577 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
578 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
579 list_append(list_T *l, listitem_T *item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
580 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
581 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
582 if (l->lv_u.mat.lv_last == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
583 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
584 // empty list
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
585 l->lv_first = item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
586 item->li_prev = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
587 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
588 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
589 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
590 l->lv_u.mat.lv_last->li_next = item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
591 item->li_prev = l->lv_u.mat.lv_last;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
592 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
593 l->lv_u.mat.lv_last = item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
594 ++l->lv_len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
595 item->li_next = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
596 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
597
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
598 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
599 * Append typval_T "tv" to the end of list "l". "tv" is copied.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
600 * Return FAIL when out of memory or the type is wrong.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
601 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
602 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
603 list_append_tv(list_T *l, typval_T *tv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
604 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
605 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
606
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
607 if (l->lv_type != NULL && l->lv_type->tt_member != NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
608 && check_typval_arg_type(l->lv_type->tt_member, tv,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
609 NULL, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
610 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
611 li = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
612 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
613 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
614 copy_tv(tv, &li->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
615 list_append(l, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
616 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
617 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
618
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
619 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
620 * As list_append_tv() but move the value instead of copying it.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
621 * Return FAIL when out of memory.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
622 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
623 static int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
624 list_append_tv_move(list_T *l, typval_T *tv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
625 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
626 listitem_T *li = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
627
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
628 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
629 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
630 li->li_tv = *tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
631 list_append(l, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
632 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
633 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
634
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
635 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
636 * Add a dictionary to a list. Used by getqflist().
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
637 * Return FAIL when out of memory.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
638 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
639 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
640 list_append_dict(list_T *list, dict_T *dict)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
641 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
642 listitem_T *li = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
643
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
644 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
645 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
646 li->li_tv.v_type = VAR_DICT;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
647 li->li_tv.v_lock = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
648 li->li_tv.vval.v_dict = dict;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
649 list_append(list, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
650 ++dict->dv_refcount;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
651 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
652 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
653
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
654 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
655 * Append list2 to list1.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
656 * Return FAIL when out of memory.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
657 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
658 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
659 list_append_list(list_T *list1, list_T *list2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
660 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
661 listitem_T *li = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
662
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
663 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
664 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
665 li->li_tv.v_type = VAR_LIST;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
666 li->li_tv.v_lock = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
667 li->li_tv.vval.v_list = list2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
668 list_append(list1, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
669 ++list2->lv_refcount;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
670 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
671 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
672
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
673 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
674 * Make a copy of "str" and append it as an item to list "l".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
675 * When "len" >= 0 use "str[len]".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
676 * Returns FAIL when out of memory.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
677 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
678 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
679 list_append_string(list_T *l, char_u *str, int len)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
680 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
681 listitem_T *li = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
682
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
683 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
684 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
685 list_append(l, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
686 li->li_tv.v_type = VAR_STRING;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
687 li->li_tv.v_lock = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
688 if (str == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
689 li->li_tv.vval.v_string = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
690 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
691 : vim_strsave(str))) == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
692 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
693 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
694 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
695
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
696 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
697 * Append "n" to list "l".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
698 * Returns FAIL when out of memory.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
699 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
700 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
701 list_append_number(list_T *l, varnumber_T n)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
702 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
703 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
704
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
705 li = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
706 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
707 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
708 li->li_tv.v_type = VAR_NUMBER;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
709 li->li_tv.v_lock = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
710 li->li_tv.vval.v_number = n;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
711 list_append(l, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
712 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
713 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
714
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
715 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
716 * Insert typval_T "tv" in list "l" before "item".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
717 * If "item" is NULL append at the end.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
718 * Return FAIL when out of memory or the type is wrong.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
719 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
720 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
721 list_insert_tv(list_T *l, typval_T *tv, listitem_T *item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
722 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
723 listitem_T *ni;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
724
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
725 if (l->lv_type != NULL && l->lv_type->tt_member != NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
726 && check_typval_arg_type(l->lv_type->tt_member, tv,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
727 NULL, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
728 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
729 ni = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
730 if (ni == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
731 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
732 copy_tv(tv, &ni->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
733 list_insert(l, ni, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
734 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
735 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
736
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
737 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
738 list_insert(list_T *l, listitem_T *ni, listitem_T *item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
739 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
740 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
741 if (item == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
742 // Append new item at end of list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
743 list_append(l, ni);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
744 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
745 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
746 // Insert new item before existing item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
747 ni->li_prev = item->li_prev;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
748 ni->li_next = item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
749 if (item->li_prev == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
750 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
751 l->lv_first = ni;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
752 ++l->lv_u.mat.lv_idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
753 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
754 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
755 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
756 item->li_prev->li_next = ni;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
757 l->lv_u.mat.lv_idx_item = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
758 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
759 item->li_prev = ni;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
760 ++l->lv_len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
761 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
762 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
763
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
764 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
765 * Get the list item in "l" with index "n1". "n1" is adjusted if needed.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
766 * In Vim9, it is at the end of the list, add an item if "can_append" is TRUE.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
767 * Return NULL if there is no such item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
768 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
769 listitem_T *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
770 check_range_index_one(list_T *l, long *n1, int can_append, int quiet)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
771 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
772 long orig_n1 = *n1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
773 listitem_T *li = list_find_index(l, n1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
774
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
775 if (li != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
776 return li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
777
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
778 // Vim9: Allow for adding an item at the end.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
779 if (can_append && in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
780 && *n1 == l->lv_len && l->lv_lock == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
781 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
782 list_append_number(l, 0);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
783 li = list_find_index(l, n1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
784 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
785 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
786 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
787 if (!quiet)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
788 semsg(_(e_list_index_out_of_range_nr), orig_n1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
789 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
790 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
791 return li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
792 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
793
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
794 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
795 * Check that "n2" can be used as the second index in a range of list "l".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
796 * If "n1" or "n2" is negative it is changed to the positive index.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
797 * "li1" is the item for item "n1".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
798 * Return OK or FAIL.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
799 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
800 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
801 check_range_index_two(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
802 list_T *l,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
803 long *n1,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
804 listitem_T *li1,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
805 long *n2,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
806 int quiet)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
807 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
808 if (*n2 < 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
809 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
810 listitem_T *ni = list_find(l, *n2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
811
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
812 if (ni == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
813 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
814 if (!quiet)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
815 semsg(_(e_list_index_out_of_range_nr), *n2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
816 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
817 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
818 *n2 = list_idx_of_item(l, ni);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
819 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
820
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
821 // Check that n2 isn't before n1.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
822 if (*n1 < 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
823 *n1 = list_idx_of_item(l, li1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
824 if (*n2 < *n1)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
825 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
826 if (!quiet)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
827 semsg(_(e_list_index_out_of_range_nr), *n2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
828 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
829 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
830 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
831 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
832
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
833 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
834 * Assign values from list "src" into a range of "dest".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
835 * "idx1_arg" is the index of the first item in "dest" to be replaced.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
836 * "idx2" is the index of last item to be replaced, but when "empty_idx2" is
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
837 * TRUE then replace all items after "idx1".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
838 * "op" is the operator, normally "=" but can be "+=" and the like.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
839 * "varname" is used for error messages.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
840 * Returns OK or FAIL.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
841 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
842 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
843 list_assign_range(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
844 list_T *dest,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
845 list_T *src,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
846 long idx1_arg,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
847 long idx2,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
848 int empty_idx2,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
849 char_u *op,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
850 char_u *varname)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
851 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
852 listitem_T *src_li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
853 listitem_T *dest_li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
854 long idx1 = idx1_arg;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
855 listitem_T *first_li = list_find_index(dest, &idx1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
856 long idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
857 type_T *member_type = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
858
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
859 // Check whether any of the list items is locked before making any changes.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
860 idx = idx1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
861 dest_li = first_li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
862 for (src_li = src->lv_first; src_li != NULL && dest_li != NULL; )
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
863 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
864 if (value_check_lock(dest_li->li_tv.v_lock, varname, FALSE))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
865 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
866 src_li = src_li->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
867 if (src_li == NULL || (!empty_idx2 && idx2 == idx))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
868 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
869 dest_li = dest_li->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
870 ++idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
871 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
872
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
873 if (in_vim9script() && dest->lv_type != NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
874 && dest->lv_type->tt_member != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
875 member_type = dest->lv_type->tt_member;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
876
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
877 // Assign the List values to the list items.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
878 idx = idx1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
879 dest_li = first_li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
880 for (src_li = src->lv_first; src_li != NULL; )
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
881 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
882 if (op != NULL && *op != '=')
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
883 tv_op(&dest_li->li_tv, &src_li->li_tv, op);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
884 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
885 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
886 if (member_type != NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
887 && check_typval_arg_type(member_type, &src_li->li_tv,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
888 NULL, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
889 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
890 clear_tv(&dest_li->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
891 copy_tv(&src_li->li_tv, &dest_li->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
892 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
893 src_li = src_li->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
894 if (src_li == NULL || (!empty_idx2 && idx2 == idx))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
895 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
896 if (dest_li->li_next == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
897 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
898 // Need to add an empty item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
899 if (list_append_number(dest, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
900 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
901 src_li = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
902 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
903 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
904 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
905 dest_li = dest_li->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
906 ++idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
907 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
908 if (src_li != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
909 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
910 emsg(_(e_list_value_has_more_items_than_targets));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
911 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
912 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
913 if (empty_idx2
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
914 ? (dest_li != NULL && dest_li->li_next != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
915 : idx != idx2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
916 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
917 emsg(_(e_list_value_does_not_have_enough_items));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
918 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
919 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
920 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
921 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
922
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
923 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
924 * Flatten up to "maxitems" in "list", starting at "first" to depth "maxdepth".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
925 * When "first" is NULL use the first item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
926 * It does nothing if "maxdepth" is 0.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
927 * Returns FAIL when out of memory.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
928 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
929 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
930 list_flatten(list_T *list, listitem_T *first, long maxitems, long maxdepth)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
931 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
932 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
933 int done = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
934
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
935 if (maxdepth == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
936 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
937 CHECK_LIST_MATERIALIZE(list);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
938 if (first == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
939 item = list->lv_first;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
940 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
941 item = first;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
942
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
943 while (item != NULL && done < maxitems)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
944 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
945 listitem_T *next = item->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
946
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
947 fast_breakcheck();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
948 if (got_int)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
949 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
950
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
951 if (item->li_tv.v_type == VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
952 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
953 list_T *itemlist = item->li_tv.vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
954
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
955 vimlist_remove(list, item, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
956 if (list_extend(list, itemlist, next) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
957 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
958 list_free_item(list, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
959 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
960 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
961
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
962 if (maxdepth > 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
963 list_flatten(list, item->li_prev == NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
964 ? list->lv_first : item->li_prev->li_next,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
965 itemlist->lv_len, maxdepth - 1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
966 clear_tv(&item->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
967 list_free_item(list, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
968 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
969
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
970 ++done;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
971 item = next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
972 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
973 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
974
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
975 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
976 * "flatten()" and "flattennew()" functions
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
977 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
978 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
979 flatten_common(typval_T *argvars, typval_T *rettv, int make_copy)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
980 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
981 list_T *l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
982 long maxdepth;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
983 int error = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
984
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
985 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
986 && (check_for_list_arg(argvars, 0) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
987 || check_for_opt_number_arg(argvars, 1) == FAIL))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
988 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
989
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
990 if (argvars[0].v_type != VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
991 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
992 semsg(_(e_argument_of_str_must_be_list), "flatten()");
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
993 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
994 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
995
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
996 if (argvars[1].v_type == VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
997 maxdepth = 999999;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
998 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
999 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1000 maxdepth = (long)tv_get_number_chk(&argvars[1], &error);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1001 if (error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1002 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1003 if (maxdepth < 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1004 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1005 emsg(_(e_maxdepth_must_be_non_negative_number));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1006 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1007 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1008 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1009
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1010 l = argvars[0].vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1011 rettv->v_type = VAR_LIST;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1012 rettv->vval.v_list = l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1013 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1014 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1015
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1016 if (make_copy)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1017 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1018 l = list_copy(l, FALSE, TRUE, get_copyID());
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1019 rettv->vval.v_list = l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1020 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1021 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1022 // The type will change.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1023 free_type(l->lv_type);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1024 l->lv_type = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1025 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1026 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1027 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1028 if (value_check_lock(l->lv_lock,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1029 (char_u *)N_("flatten() argument"), TRUE))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1030 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1031 ++l->lv_refcount;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1032 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1033
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1034 list_flatten(l, NULL, l->lv_len, maxdepth);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1035 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1036
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1037 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1038 * "flatten(list[, {maxdepth}])" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1039 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1040 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1041 f_flatten(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1042 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1043 if (in_vim9script())
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1044 emsg(_(e_cannot_use_flatten_in_vim9_script));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1045 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1046 flatten_common(argvars, rettv, FALSE);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1047 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1048
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1049 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1050 * "flattennew(list[, {maxdepth}])" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1051 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1052 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1053 f_flattennew(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1054 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1055 flatten_common(argvars, rettv, TRUE);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1056 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1057
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1058 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1059 * "items(list)" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1060 * Caller must have already checked that argvars[0] is a List.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1061 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1062 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1063 list2items(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1064 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1065 list_T *l = argvars[0].vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1066 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1067 varnumber_T idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1068
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1069 if (rettv_list_alloc(rettv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1070 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1071 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1072 return; // null list behaves like an empty list
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1073
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1074 // TODO: would be more efficient to not materialize the argument
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1075 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1076 for (idx = 0, li = l->lv_first; li != NULL; li = li->li_next, ++idx)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1077 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1078 list_T *l2 = list_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1079
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1080 if (l2 == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1081 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1082 if (list_append_list(rettv->vval.v_list, l2) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1083 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1084 vim_free(l2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1085 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1086 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1087 if (list_append_number(l2, idx) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1088 || list_append_tv(l2, &li->li_tv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1089 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1090 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1091 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1092
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1093 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1094 * "items(string)" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1095 * Caller must have already checked that argvars[0] is a String.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1096 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1097 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1098 string2items(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1099 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1100 char_u *p = argvars[0].vval.v_string;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1101 varnumber_T idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1102
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1103 if (rettv_list_alloc(rettv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1104 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1105 if (p == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1106 return; // null string behaves like an empty string
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1107
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1108 for (idx = 0; *p != NUL; ++idx)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1109 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1110 int len = mb_ptr2len(p);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1111 list_T *l2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1112
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1113 if (len == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1114 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1115 l2 = list_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1116 if (l2 == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1117 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1118 if (list_append_list(rettv->vval.v_list, l2) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1119 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1120 vim_free(l2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1121 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1122 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1123 if (list_append_number(l2, idx) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1124 || list_append_string(l2, p, len) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1125 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1126 p += len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1127 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1128 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1129
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1130 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1131 * Extend "l1" with "l2". "l1" must not be NULL.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1132 * If "bef" is NULL append at the end, otherwise insert before this item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1133 * Returns FAIL when out of memory.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1134 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1135 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1136 list_extend(list_T *l1, list_T *l2, listitem_T *bef)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1137 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1138 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1139 int todo;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1140 listitem_T *bef_prev;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1141
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1142 // NULL list is equivalent to an empty list: nothing to do.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1143 if (l2 == NULL || l2->lv_len == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1144 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1145
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1146 todo = l2->lv_len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1147 CHECK_LIST_MATERIALIZE(l1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1148 CHECK_LIST_MATERIALIZE(l2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1149
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1150 // When exending a list with itself, at some point we run into the item
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1151 // that was before "bef" and need to skip over the already inserted items
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1152 // to "bef".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1153 bef_prev = bef == NULL ? NULL : bef->li_prev;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1154
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1155 // We also quit the loop when we have inserted the original item count of
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1156 // the list, avoid a hang when we extend a list with itself.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1157 for (item = l2->lv_first; item != NULL && --todo >= 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1158 item = item == bef_prev ? bef : item->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1159 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1160 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1161 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1162 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1163
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1164 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1165 * Concatenate lists "l1" and "l2" into a new list, stored in "tv".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1166 * Return FAIL when out of memory.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1167 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1168 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1169 list_concat(list_T *l1, list_T *l2, typval_T *tv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1170 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1171 list_T *l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1172
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1173 // make a copy of the first list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1174 if (l1 == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1175 l = list_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1176 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1177 l = list_copy(l1, FALSE, TRUE, 0);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1178 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1179 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1180 tv->v_type = VAR_LIST;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1181 tv->v_lock = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1182 tv->vval.v_list = l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1183 if (l1 == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1184 ++l->lv_refcount;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1185
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1186 // append all items from the second list
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1187 return list_extend(l, l2, NULL);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1188 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1189
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1190 list_T *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1191 list_slice(list_T *ol, long n1, long n2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1192 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1193 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1194 list_T *l = list_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1195
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1196 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1197 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1198 for (item = list_find(ol, n1); n1 <= n2; ++n1)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1199 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1200 if (list_append_tv(l, &item->li_tv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1201 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1202 list_free(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1203 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1204 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1205 item = item->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1206 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1207 return l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1208 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1209
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1210 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1211 list_slice_or_index(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1212 list_T *list,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1213 int range,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1214 varnumber_T n1_arg,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1215 varnumber_T n2_arg,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1216 int exclusive,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1217 typval_T *rettv,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1218 int verbose)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1219 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1220 long len = list_len(list);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1221 varnumber_T n1 = n1_arg;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1222 varnumber_T n2 = n2_arg;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1223 typval_T var1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1224
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1225 if (n1 < 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1226 n1 = len + n1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1227 if (n1 < 0 || n1 >= len)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1228 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1229 // For a range we allow invalid values and for legacy script return an
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1230 // empty list, for Vim9 script start at the first item.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1231 // A list index out of range is an error.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1232 if (!range)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1233 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1234 if (verbose)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1235 semsg(_(e_list_index_out_of_range_nr), (long)n1_arg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1236 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1237 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1238 if (in_vim9script())
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1239 n1 = n1 < 0 ? 0 : len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1240 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1241 n1 = len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1242 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1243 if (range)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1244 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1245 list_T *l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1246
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1247 if (n2 < 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1248 n2 = len + n2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1249 else if (n2 >= len)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1250 n2 = len - (exclusive ? 0 : 1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1251 if (exclusive)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1252 --n2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1253 if (n2 < 0 || n2 + 1 < n1)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1254 n2 = -1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1255 l = list_slice(list, n1, n2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1256 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1257 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1258 clear_tv(rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1259 rettv_list_set(rettv, l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1260 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1261 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1262 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1263 // copy the item to "var1" to avoid that freeing the list makes it
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1264 // invalid.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1265 copy_tv(&list_find(list, n1)->li_tv, &var1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1266 clear_tv(rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1267 *rettv = var1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1268 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1269 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1270 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1271
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1272 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1273 * Make a copy of list "orig". Shallow if "deep" is FALSE.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1274 * The refcount of the new list is set to 1.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1275 * See item_copy() for "top" and "copyID".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1276 * Returns NULL when out of memory.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1277 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1278 list_T *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1279 list_copy(list_T *orig, int deep, int top, int copyID)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1280 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1281 list_T *copy;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1282 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1283 listitem_T *ni;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1284
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1285 if (orig == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1286 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1287
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1288 copy = list_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1289 if (copy == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1290 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1291
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1292 if (orig->lv_type == NULL || top || deep)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1293 copy->lv_type = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1294 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1295 copy->lv_type = alloc_type(orig->lv_type);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1296 if (copyID != 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1297 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1298 // Do this before adding the items, because one of the items may
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1299 // refer back to this list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1300 orig->lv_copyID = copyID;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1301 orig->lv_copylist = copy;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1302 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1303 CHECK_LIST_MATERIALIZE(orig);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1304 for (item = orig->lv_first; item != NULL && !got_int;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1305 item = item->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1306 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1307 ni = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1308 if (ni == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1309 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1310 if (deep)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1311 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1312 if (item_copy(&item->li_tv, &ni->li_tv,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1313 deep, FALSE, copyID) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1314 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1315 vim_free(ni);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1316 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1317 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1318 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1319 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1320 copy_tv(&item->li_tv, &ni->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1321 list_append(copy, ni);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1322 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1323 ++copy->lv_refcount;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1324 if (item != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1325 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1326 list_unref(copy);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1327 copy = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1328 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1329
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1330 return copy;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1331 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1332
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1333 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1334 * Remove items "item" to "item2" from list "l".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1335 * Does not free the listitem or the value!
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1336 * This used to be called list_remove, but that conflicts with a Sun header
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1337 * file.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1338 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1339 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1340 vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1341 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1342 listitem_T *ip;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1343
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1344 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1345
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1346 // notify watchers
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1347 for (ip = item; ip != NULL; ip = ip->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1348 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1349 --l->lv_len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1350 list_fix_watch(l, ip);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1351 if (ip == item2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1352 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1353 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1354
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1355 if (item2->li_next == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1356 l->lv_u.mat.lv_last = item->li_prev;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1357 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1358 item2->li_next->li_prev = item->li_prev;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1359 if (item->li_prev == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1360 l->lv_first = item2->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1361 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1362 item->li_prev->li_next = item2->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1363 l->lv_u.mat.lv_idx_item = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1364 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1365
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1366 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1367 * Return an allocated string with the string representation of a list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1368 * May return NULL.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1369 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1370 char_u *
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1371 list2string(typval_T *tv, int copyID, int restore_copyID)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1372 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1373 garray_T ga;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1374
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1375 if (tv->vval.v_list == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1376 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1377 ga_init2(&ga, sizeof(char), 80);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1378 ga_append(&ga, '[');
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1379 CHECK_LIST_MATERIALIZE(tv->vval.v_list);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1380 if (list_join(&ga, tv->vval.v_list, (char_u *)", ",
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1381 FALSE, restore_copyID, copyID) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1382 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1383 vim_free(ga.ga_data);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1384 return NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1385 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1386 ga_append(&ga, ']');
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1387 ga_append(&ga, NUL);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1388 return (char_u *)ga.ga_data;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1389 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1390
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1391 typedef struct join_S {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1392 char_u *s;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1393 char_u *tofree;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1394 } join_T;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1395
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1396 static int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1397 list_join_inner(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1398 garray_T *gap, // to store the result in
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1399 list_T *l,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1400 char_u *sep,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1401 int echo_style,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1402 int restore_copyID,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1403 int copyID,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1404 garray_T *join_gap) // to keep each list item string
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1405 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1406 int i;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1407 join_T *p;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1408 int len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1409 int sumlen = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1410 int first = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1411 char_u *tofree;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1412 char_u numbuf[NUMBUFLEN];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1413 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1414 char_u *s;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1415
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1416 // Stringify each item in the list.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1417 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1418 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1419 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1420 s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1421 echo_style, restore_copyID, !echo_style);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1422 if (s == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1423 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1424
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1425 len = (int)STRLEN(s);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1426 sumlen += len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1427
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1428 (void)ga_grow(join_gap, 1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1429 p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1430 if (tofree != NULL || s != numbuf)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1431 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1432 p->s = s;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1433 p->tofree = tofree;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1434 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1435 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1436 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1437 p->s = vim_strnsave(s, len);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1438 p->tofree = p->s;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1439 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1440
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1441 line_breakcheck();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1442 if (did_echo_string_emsg) // recursion error, bail out
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1443 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1444 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1445
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1446 // Allocate result buffer with its total size, avoid re-allocation and
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1447 // multiple copy operations. Add 2 for a tailing ']' and NUL.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1448 if (join_gap->ga_len >= 2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1449 sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1450 if (ga_grow(gap, sumlen + 2) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1451 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1452
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1453 for (i = 0; i < join_gap->ga_len && !got_int; ++i)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1454 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1455 if (first)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1456 first = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1457 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1458 ga_concat(gap, sep);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1459 p = ((join_T *)join_gap->ga_data) + i;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1460
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1461 if (p->s != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1462 ga_concat(gap, p->s);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1463 line_breakcheck();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1464 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1465
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1466 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1467 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1468
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1469 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1470 * Join list "l" into a string in "*gap", using separator "sep".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1471 * When "echo_style" is TRUE use String as echoed, otherwise as inside a List.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1472 * Return FAIL or OK.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1473 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1474 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1475 list_join(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1476 garray_T *gap,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1477 list_T *l,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1478 char_u *sep,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1479 int echo_style,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1480 int restore_copyID,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1481 int copyID)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1482 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1483 garray_T join_ga;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1484 int retval;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1485 join_T *p;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1486 int i;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1487
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1488 if (l->lv_len < 1)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1489 return OK; // nothing to do
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1490 ga_init2(&join_ga, sizeof(join_T), l->lv_len);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1491 retval = list_join_inner(gap, l, sep, echo_style, restore_copyID,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1492 copyID, &join_ga);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1493
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1494 if (join_ga.ga_data == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1495 return retval;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1496
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1497 // Dispose each item in join_ga.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1498 p = (join_T *)join_ga.ga_data;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1499 for (i = 0; i < join_ga.ga_len; ++i)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1500 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1501 vim_free(p->tofree);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1502 ++p;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1503 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1504 ga_clear(&join_ga);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1505
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1506 return retval;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1507 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1508
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1509 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1510 * "join()" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1511 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1512 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1513 f_join(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1514 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1515 garray_T ga;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1516 char_u *sep;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1517
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1518 rettv->v_type = VAR_STRING;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1519
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1520 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1521 && (check_for_list_arg(argvars, 0) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1522 || check_for_opt_string_arg(argvars, 1) == FAIL))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1523 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1524
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1525 if (check_for_list_arg(argvars, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1526 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1527
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1528 if (argvars[0].vval.v_list == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1529 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1530
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1531 if (argvars[1].v_type == VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1532 sep = (char_u *)" ";
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1533 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1534 sep = tv_get_string_chk(&argvars[1]);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1535
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1536 if (sep != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1537 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1538 ga_init2(&ga, sizeof(char), 80);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1539 list_join(&ga, argvars[0].vval.v_list, sep, TRUE, FALSE, 0);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1540 ga_append(&ga, NUL);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1541 rettv->vval.v_string = (char_u *)ga.ga_data;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1542 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1543 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1544 rettv->vval.v_string = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1545 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1546
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1547 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1548 * Allocate a variable for a List and fill it from "*arg".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1549 * "*arg" points to the "[".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1550 * Return OK or FAIL.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1551 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1552 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1553 eval_list(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int do_error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1554 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1555 int evaluate = evalarg == NULL ? FALSE
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1556 : evalarg->eval_flags & EVAL_EVALUATE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1557 list_T *l = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1558 typval_T tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1559 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1560 int vim9script = in_vim9script();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1561 int had_comma;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1562
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1563 if (evaluate)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1564 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1565 l = list_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1566 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1567 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1568 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1569
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1570 *arg = skipwhite_and_linebreak(*arg + 1, evalarg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1571 while (**arg != ']' && **arg != NUL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1572 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1573 if (eval1(arg, &tv, evalarg) == FAIL) // recursive!
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1574 goto failret;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1575 if (evaluate)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1576 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1577 item = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1578 if (item != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1579 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1580 item->li_tv = tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1581 item->li_tv.v_lock = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1582 list_append(l, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1583 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1584 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1585 clear_tv(&tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1586 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1587 // Legacy Vim script allowed a space before the comma.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1588 if (!vim9script)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1589 *arg = skipwhite(*arg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1590
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1591 // the comma must come after the value
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1592 had_comma = **arg == ',';
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1593 if (had_comma)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1594 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1595 if (vim9script && !IS_WHITE_OR_NUL((*arg)[1]) && (*arg)[1] != ']')
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1596 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1597 semsg(_(e_white_space_required_after_str_str), ",", *arg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1598 goto failret;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1599 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1600 *arg = skipwhite(*arg + 1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1601 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1602
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1603 // The "]" can be on the next line. But a double quoted string may
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1604 // follow, not a comment.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1605 *arg = skipwhite_and_linebreak(*arg, evalarg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1606 if (**arg == ']')
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1607 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1608
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1609 if (!had_comma)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1610 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1611 if (do_error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1612 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1613 if (**arg == ',')
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1614 semsg(_(e_no_white_space_allowed_before_str_str),
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1615 ",", *arg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1616 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1617 semsg(_(e_missing_comma_in_list_str), *arg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1618 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1619 goto failret;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1620 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1621 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1622
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1623 if (**arg != ']')
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1624 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1625 if (do_error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1626 semsg(_(e_missing_end_of_list_rsb_str), *arg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1627 failret:
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1628 if (evaluate)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1629 list_free(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1630 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1631 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1632
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1633 *arg += 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1634 if (evaluate)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1635 rettv_list_set(rettv, l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1636
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1637 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1638 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1639
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1640 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1641 * Write "list" of strings to file "fd".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1642 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1643 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1644 write_list(FILE *fd, list_T *list, int binary)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1645 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1646 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1647 int c;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1648 int ret = OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1649 char_u *s;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1650
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1651 CHECK_LIST_MATERIALIZE(list);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1652 FOR_ALL_LIST_ITEMS(list, li)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1653 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1654 for (s = tv_get_string(&li->li_tv); *s != NUL; ++s)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1655 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1656 if (*s == '\n')
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1657 c = putc(NUL, fd);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1658 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1659 c = putc(*s, fd);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1660 if (c == EOF)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1661 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1662 ret = FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1663 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1664 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1665 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1666 if (!binary || li->li_next != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1667 if (putc('\n', fd) == EOF)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1668 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1669 ret = FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1670 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1671 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1672 if (ret == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1673 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1674 emsg(_(e_error_while_writing));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1675 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1676 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1677 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1678 return ret;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1679 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1680
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1681 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1682 * Initialize a static list with 10 items.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1683 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1684 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1685 init_static_list(staticList10_T *sl)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1686 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1687 list_T *l = &sl->sl_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1688 int i;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1689
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1690 CLEAR_POINTER(sl);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1691 l->lv_first = &sl->sl_items[0];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1692 l->lv_u.mat.lv_last = &sl->sl_items[9];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1693 l->lv_refcount = DO_NOT_FREE_CNT;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1694 l->lv_lock = VAR_FIXED;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1695 sl->sl_list.lv_len = 10;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1696
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1697 for (i = 0; i < 10; ++i)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1698 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1699 listitem_T *li = &sl->sl_items[i];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1700
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1701 if (i == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1702 li->li_prev = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1703 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1704 li->li_prev = li - 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1705 if (i == 9)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1706 li->li_next = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1707 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1708 li->li_next = li + 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1709 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1710 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1711
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1712 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1713 * "list2str()" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1714 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1715 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1716 f_list2str(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1717 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1718 list_T *l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1719 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1720 garray_T ga;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1721 int utf8 = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1722
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1723 rettv->v_type = VAR_STRING;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1724 rettv->vval.v_string = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1725
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1726 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1727 && (check_for_list_arg(argvars, 0) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1728 || check_for_opt_bool_arg(argvars, 1) == FAIL))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1729 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1730
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1731 if (check_for_list_arg(argvars, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1732 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1733
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1734 l = argvars[0].vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1735 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1736 return; // empty list results in empty string
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1737
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1738 if (argvars[1].v_type != VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1739 utf8 = (int)tv_get_bool_chk(&argvars[1], NULL);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1740
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1741 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1742 ga_init2(&ga, 1, 80);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1743 if (has_mbyte || utf8)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1744 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1745 char_u buf[MB_MAXBYTES + 1];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1746 int (*char2bytes)(int, char_u *);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1747
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1748 if (utf8 || enc_utf8)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1749 char2bytes = utf_char2bytes;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1750 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1751 char2bytes = mb_char2bytes;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1752
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1753 FOR_ALL_LIST_ITEMS(l, li)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1754 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1755 buf[(*char2bytes)(tv_get_number(&li->li_tv), buf)] = NUL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1756 ga_concat(&ga, buf);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1757 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1758 ga_append(&ga, NUL);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1759 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1760 else if (ga_grow(&ga, list_len(l) + 1) == OK)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1761 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1762 FOR_ALL_LIST_ITEMS(l, li)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1763 ga_append(&ga, tv_get_number(&li->li_tv));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1764 ga_append(&ga, NUL);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1765 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1766
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1767 rettv->v_type = VAR_STRING;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1768 rettv->vval.v_string = ga.ga_data;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1769 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1770
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1771 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1772 * Remove item argvars[1] from List argvars[0]. If argvars[2] is supplied, then
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1773 * remove the range of items from argvars[1] to argvars[2] (inclusive).
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1774 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1775 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1776 list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1777 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1778 list_T *l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1779 listitem_T *item, *item2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1780 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1781 int error = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1782 long idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1783 long end;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1784 int cnt = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1785 list_T *rl;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1786
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1787 if ((l = argvars[0].vval.v_list) == NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1788 || value_check_lock(l->lv_lock, arg_errmsg, TRUE))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1789 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1790
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1791 idx = (long)tv_get_number_chk(&argvars[1], &error);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1792 if (error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1793 return; // type error: do nothing, errmsg already given
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1794
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1795 if ((item = list_find(l, idx)) == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1796 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1797 semsg(_(e_list_index_out_of_range_nr), idx);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1798 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1799 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1800
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1801 if (argvars[2].v_type == VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1802 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1803 // Remove one item, return its value.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1804 vimlist_remove(l, item, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1805 *rettv = item->li_tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1806 list_free_item(l, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1807 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1808 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1809
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1810 // Remove range of items, return list with values.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1811 end = (long)tv_get_number_chk(&argvars[2], &error);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1812 if (error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1813 return; // type error: do nothing
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1814
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1815 if ((item2 = list_find(l, end)) == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1816 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1817 semsg(_(e_list_index_out_of_range_nr), end);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1818 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1819 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1820
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1821 for (li = item; li != NULL; li = li->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1822 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1823 ++cnt;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1824 if (li == item2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1825 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1826 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1827 if (li == NULL) // didn't find "item2" after "item"
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1828 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1829 emsg(_(e_invalid_range));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1830 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1831 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1832
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1833 vimlist_remove(l, item, item2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1834 if (rettv_list_alloc(rettv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1835 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1836
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1837 rl = rettv->vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1838
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1839 if (l->lv_with_items > 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1840 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1841 // need to copy the list items and move the value
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1842 while (item != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1843 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1844 li = listitem_alloc();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1845 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1846 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1847 li->li_tv = item->li_tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1848 init_tv(&item->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1849 list_append(rl, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1850 if (item == item2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1851 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1852 item = item->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1853 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1854 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1855 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1856 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1857 rl->lv_first = item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1858 rl->lv_u.mat.lv_last = item2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1859 item->li_prev = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1860 item2->li_next = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1861 rl->lv_len = cnt;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1862 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1863 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1864
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1865 static int item_compare(const void *s1, const void *s2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1866 static int item_compare2(const void *s1, const void *s2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1867
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1868 // struct used in the array that's given to qsort()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1869 typedef struct
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1870 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1871 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1872 int idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1873 } sortItem_T;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1874
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1875 // struct storing information about current sort
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1876 typedef struct
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1877 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1878 int item_compare_ic;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1879 int item_compare_lc;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1880 int item_compare_numeric;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1881 int item_compare_numbers;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1882 int item_compare_float;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1883 char_u *item_compare_func;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1884 partial_T *item_compare_partial;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1885 dict_T *item_compare_selfdict;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1886 int item_compare_func_err;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1887 int item_compare_keep_zero;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1888 } sortinfo_T;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1889 static sortinfo_T *sortinfo = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1890 #define ITEM_COMPARE_FAIL 999
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1891
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1892 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1893 * Compare functions for f_sort() and f_uniq() below.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1894 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1895 static int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1896 item_compare(const void *s1, const void *s2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1897 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1898 sortItem_T *si1, *si2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1899 typval_T *tv1, *tv2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1900 char_u *p1, *p2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1901 char_u *tofree1 = NULL, *tofree2 = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1902 int res;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1903 char_u numbuf1[NUMBUFLEN];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1904 char_u numbuf2[NUMBUFLEN];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1905
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1906 si1 = (sortItem_T *)s1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1907 si2 = (sortItem_T *)s2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1908 tv1 = &si1->item->li_tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1909 tv2 = &si2->item->li_tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1910
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1911 if (sortinfo->item_compare_numbers)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1912 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1913 varnumber_T v1 = tv_to_number(tv1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1914 varnumber_T v2 = tv_to_number(tv2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1915
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1916 return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1917 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1918
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1919 if (sortinfo->item_compare_float)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1920 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1921 float_T v1 = tv_get_float(tv1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1922 float_T v2 = tv_get_float(tv2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1923
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1924 return v1 == v2 ? 0 : v1 > v2 ? 1 : -1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1925 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1926
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1927 // tv2string() puts quotes around a string and allocates memory. Don't do
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1928 // that for string variables. Use a single quote when comparing with a
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1929 // non-string to do what the docs promise.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1930 if (tv1->v_type == VAR_STRING)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1931 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1932 if (tv2->v_type != VAR_STRING || sortinfo->item_compare_numeric)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1933 p1 = (char_u *)"'";
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1934 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1935 p1 = tv1->vval.v_string;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1936 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1937 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1938 p1 = tv2string(tv1, &tofree1, numbuf1, 0);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1939 if (tv2->v_type == VAR_STRING)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1940 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1941 if (tv1->v_type != VAR_STRING || sortinfo->item_compare_numeric)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1942 p2 = (char_u *)"'";
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1943 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1944 p2 = tv2->vval.v_string;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1945 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1946 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1947 p2 = tv2string(tv2, &tofree2, numbuf2, 0);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1948 if (p1 == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1949 p1 = (char_u *)"";
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1950 if (p2 == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1951 p2 = (char_u *)"";
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1952 if (!sortinfo->item_compare_numeric)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1953 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1954 if (sortinfo->item_compare_lc)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1955 res = strcoll((char *)p1, (char *)p2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1956 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1957 res = sortinfo->item_compare_ic ? STRICMP(p1, p2): STRCMP(p1, p2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1958 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1959 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1960 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1961 double n1, n2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1962 n1 = strtod((char *)p1, (char **)&p1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1963 n2 = strtod((char *)p2, (char **)&p2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1964 res = n1 == n2 ? 0 : n1 > n2 ? 1 : -1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1965 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1966
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1967 // When the result would be zero, compare the item indexes. Makes the
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1968 // sort stable.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1969 if (res == 0 && !sortinfo->item_compare_keep_zero)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1970 res = si1->idx > si2->idx ? 1 : -1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1971
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1972 vim_free(tofree1);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1973 vim_free(tofree2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1974 return res;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1975 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1976
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1977 static int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1978 item_compare2(const void *s1, const void *s2)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1979 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1980 sortItem_T *si1, *si2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1981 int res;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1982 typval_T rettv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1983 typval_T argv[3];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1984 char_u *func_name;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1985 partial_T *partial = sortinfo->item_compare_partial;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1986 funcexe_T funcexe;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1987 int did_emsg_before = did_emsg;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1988
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1989 // shortcut after failure in previous call; compare all items equal
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1990 if (sortinfo->item_compare_func_err)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1991 return 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1992
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1993 si1 = (sortItem_T *)s1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1994 si2 = (sortItem_T *)s2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1995
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1996 if (partial == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1997 func_name = sortinfo->item_compare_func;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1998 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
1999 func_name = partial_name(partial);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2000
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2001 // Copy the values. This is needed to be able to set v_lock to VAR_FIXED
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2002 // in the copy without changing the original list items.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2003 copy_tv(&si1->item->li_tv, &argv[0]);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2004 copy_tv(&si2->item->li_tv, &argv[1]);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2005
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2006 rettv.v_type = VAR_UNKNOWN; // clear_tv() uses this
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2007 CLEAR_FIELD(funcexe);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2008 funcexe.fe_evaluate = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2009 funcexe.fe_partial = partial;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2010 funcexe.fe_selfdict = sortinfo->item_compare_selfdict;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2011 res = call_func(func_name, -1, &rettv, 2, argv, &funcexe);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2012 clear_tv(&argv[0]);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2013 clear_tv(&argv[1]);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2014
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2015 if (res == FAIL || did_emsg > did_emsg_before)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2016 res = ITEM_COMPARE_FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2017 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2018 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2019 res = (int)tv_get_number_chk(&rettv, &sortinfo->item_compare_func_err);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2020 if (res > 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2021 res = 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2022 else if (res < 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2023 res = -1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2024 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2025 if (sortinfo->item_compare_func_err)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2026 res = ITEM_COMPARE_FAIL; // return value has wrong type
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2027 clear_tv(&rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2028
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2029 // When the result would be zero, compare the pointers themselves. Makes
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2030 // the sort stable.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2031 if (res == 0 && !sortinfo->item_compare_keep_zero)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2032 res = si1->idx > si2->idx ? 1 : -1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2033
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2034 return res;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2035 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2036
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2037 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2038 * sort() List "l"
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2039 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2040 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2041 do_sort(list_T *l, sortinfo_T *info)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2042 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2043 long len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2044 sortItem_T *ptrs;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2045 long i = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2046 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2047
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2048 len = list_len(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2049
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2050 // Make an array with each entry pointing to an item in the List.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2051 ptrs = ALLOC_MULT(sortItem_T, len);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2052 if (ptrs == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2053 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2054
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2055 // sort(): ptrs will be the list to sort
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2056 FOR_ALL_LIST_ITEMS(l, li)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2057 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2058 ptrs[i].item = li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2059 ptrs[i].idx = i;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2060 ++i;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2061 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2062
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2063 info->item_compare_func_err = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2064 info->item_compare_keep_zero = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2065 // test the compare function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2066 if ((info->item_compare_func != NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2067 || info->item_compare_partial != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2068 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2069 == ITEM_COMPARE_FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2070 emsg(_(e_sort_compare_function_failed));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2071 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2072 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2073 // Sort the array with item pointers.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2074 qsort((void *)ptrs, (size_t)len, sizeof(sortItem_T),
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2075 info->item_compare_func == NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2076 && info->item_compare_partial == NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2077 ? item_compare : item_compare2);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2078
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2079 if (!info->item_compare_func_err)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2080 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2081 // Clear the List and append the items in sorted order.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2082 l->lv_first = l->lv_u.mat.lv_last
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2083 = l->lv_u.mat.lv_idx_item = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2084 l->lv_len = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2085 for (i = 0; i < len; ++i)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2086 list_append(l, ptrs[i].item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2087 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2088 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2089
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2090 vim_free(ptrs);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2091 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2092
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2093 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2094 * uniq() List "l"
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2095 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2096 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2097 do_uniq(list_T *l, sortinfo_T *info)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2098 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2099 long len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2100 sortItem_T *ptrs;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2101 long i = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2102 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2103 int (*item_compare_func_ptr)(const void *, const void *);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2104
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2105 len = list_len(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2106
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2107 // Make an array with each entry pointing to an item in the List.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2108 ptrs = ALLOC_MULT(sortItem_T, len);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2109 if (ptrs == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2110 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2111
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2112 // f_uniq(): ptrs will be a stack of items to remove
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2113 info->item_compare_func_err = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2114 info->item_compare_keep_zero = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2115 item_compare_func_ptr = info->item_compare_func != NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2116 || info->item_compare_partial != NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2117 ? item_compare2 : item_compare;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2118
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2119 for (li = l->lv_first; li != NULL && li->li_next != NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2120 li = li->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2121 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2122 if (item_compare_func_ptr((void *)&li, (void *)&li->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2123 == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2124 ptrs[i++].item = li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2125 if (info->item_compare_func_err)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2126 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2127 emsg(_(e_uniq_compare_function_failed));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2128 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2129 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2130 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2131
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2132 if (!info->item_compare_func_err)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2133 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2134 while (--i >= 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2135 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2136 li = ptrs[i].item->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2137 ptrs[i].item->li_next = li->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2138 if (li->li_next != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2139 li->li_next->li_prev = ptrs[i].item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2140 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2141 l->lv_u.mat.lv_last = ptrs[i].item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2142 list_fix_watch(l, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2143 listitem_free(l, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2144 l->lv_len--;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2145 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2146 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2147
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2148 vim_free(ptrs);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2149 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2150
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2151 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2152 * Parse the optional arguments supplied to the sort() or uniq() function and
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2153 * return the values in "info".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2154 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2155 static int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2156 parse_sort_uniq_args(typval_T *argvars, sortinfo_T *info)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2157 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2158 info->item_compare_ic = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2159 info->item_compare_lc = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2160 info->item_compare_numeric = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2161 info->item_compare_numbers = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2162 info->item_compare_float = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2163 info->item_compare_func = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2164 info->item_compare_partial = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2165 info->item_compare_selfdict = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2166
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2167 if (argvars[1].v_type == VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2168 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2169
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2170 // optional second argument: {func}
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2171 if (argvars[1].v_type == VAR_FUNC)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2172 info->item_compare_func = argvars[1].vval.v_string;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2173 else if (argvars[1].v_type == VAR_PARTIAL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2174 info->item_compare_partial = argvars[1].vval.v_partial;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2175 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2176 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2177 int error = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2178 int nr = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2179
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2180 if (argvars[1].v_type == VAR_NUMBER)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2181 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2182 nr = tv_get_number_chk(&argvars[1], &error);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2183 if (error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2184 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2185 if (nr == 1)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2186 info->item_compare_ic = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2187 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2188 if (nr != 1)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2189 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2190 if (argvars[1].v_type != VAR_NUMBER)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2191 info->item_compare_func = tv_get_string(&argvars[1]);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2192 else if (nr != 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2193 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2194 emsg(_(e_invalid_argument));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2195 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2196 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2197 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2198 if (info->item_compare_func != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2199 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2200 if (*info->item_compare_func == NUL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2201 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2202 // empty string means default sort
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2203 info->item_compare_func = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2204 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2205 else if (STRCMP(info->item_compare_func, "n") == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2206 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2207 info->item_compare_func = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2208 info->item_compare_numeric = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2209 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2210 else if (STRCMP(info->item_compare_func, "N") == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2211 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2212 info->item_compare_func = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2213 info->item_compare_numbers = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2214 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2215 else if (STRCMP(info->item_compare_func, "f") == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2216 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2217 info->item_compare_func = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2218 info->item_compare_float = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2219 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2220 else if (STRCMP(info->item_compare_func, "i") == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2221 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2222 info->item_compare_func = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2223 info->item_compare_ic = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2224 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2225 else if (STRCMP(info->item_compare_func, "l") == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2226 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2227 info->item_compare_func = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2228 info->item_compare_lc = TRUE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2229 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2230 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2231 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2232
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2233 if (argvars[2].v_type != VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2234 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2235 // optional third argument: {dict}
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2236 if (check_for_dict_arg(argvars, 2) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2237 return FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2238 info->item_compare_selfdict = argvars[2].vval.v_dict;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2239 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2240
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2241 return OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2242 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2243
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2244 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2245 * "sort()" or "uniq()" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2246 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2247 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2248 do_sort_uniq(typval_T *argvars, typval_T *rettv, int sort)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2249 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2250 list_T *l;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2251 sortinfo_T *old_sortinfo;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2252 sortinfo_T info;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2253 long len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2254
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2255 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2256 && (check_for_list_arg(argvars, 0) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2257 || (argvars[1].v_type != VAR_UNKNOWN
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2258 && (check_for_string_or_func_arg(argvars, 1) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2259 || check_for_opt_dict_arg(argvars, 2) == FAIL))))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2260 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2261
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2262 if (argvars[0].v_type != VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2263 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2264 semsg(_(e_argument_of_str_must_be_list), sort ? "sort()" : "uniq()");
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2265 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2266 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2267
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2268 // Pointer to current info struct used in compare function. Save and
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2269 // restore the current one for nested calls.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2270 old_sortinfo = sortinfo;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2271 sortinfo = &info;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2272
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2273 l = argvars[0].vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2274 if (l != NULL && value_check_lock(l->lv_lock,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2275 (char_u *)(sort ? N_("sort() argument") : N_("uniq() argument")),
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2276 TRUE))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2277 goto theend;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2278 rettv_list_set(rettv, l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2279 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2280 goto theend;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2281 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2282
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2283 len = list_len(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2284 if (len <= 1)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2285 goto theend; // short list sorts pretty quickly
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2286
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2287 if (parse_sort_uniq_args(argvars, &info) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2288 goto theend;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2289
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2290 if (sort)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2291 do_sort(l, &info);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2292 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2293 do_uniq(l, &info);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2294
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2295 theend:
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2296 sortinfo = old_sortinfo;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2297 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2298
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2299 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2300 * "sort({list})" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2301 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2302 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2303 f_sort(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2304 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2305 do_sort_uniq(argvars, rettv, TRUE);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2306 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2307
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2308 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2309 * "uniq({list})" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2310 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2311 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2312 f_uniq(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2313 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2314 do_sort_uniq(argvars, rettv, FALSE);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2315 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2316
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2317 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2318 * Handle one item for map() and filter().
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2319 * Sets v:val to "tv". Caller must set v:key.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2320 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2321 int
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2322 filter_map_one(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2323 typval_T *tv, // original value
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2324 typval_T *expr, // callback
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2325 filtermap_T filtermap,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2326 funccall_T *fc, // from eval_expr_get_funccal()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2327 typval_T *newtv, // for map() and mapnew(): new value
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2328 int *remp) // for filter(): remove flag
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2329 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2330 typval_T argv[3];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2331 int retval = FAIL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2332
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2333 copy_tv(tv, get_vim_var_tv(VV_VAL));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2334 argv[0] = *get_vim_var_tv(VV_KEY);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2335 argv[1] = *get_vim_var_tv(VV_VAL);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2336 if (eval_expr_typval(expr, argv, 2, fc, newtv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2337 goto theend;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2338 if (filtermap == FILTERMAP_FILTER)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2339 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2340 int error = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2341
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2342 // filter(): when expr is zero remove the item
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2343 if (in_vim9script())
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2344 *remp = !tv_get_bool_chk(newtv, &error);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2345 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2346 *remp = (tv_get_number_chk(newtv, &error) == 0);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2347 clear_tv(newtv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2348 // On type error, nothing has been removed; return FAIL to stop the
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2349 // loop. The error message was given by tv_get_number_chk().
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2350 if (error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2351 goto theend;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2352 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2353 retval = OK;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2354 theend:
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2355 clear_tv(get_vim_var_tv(VV_VAL));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2356 return retval;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2357 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2358
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2359 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2360 * Implementation of map() and filter() for a List. Apply "expr" to every item
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2361 * in List "l" and return the result in "rettv".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2362 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2363 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2364 list_filter_map(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2365 list_T *l,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2366 filtermap_T filtermap,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2367 type_T *argtype,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2368 char *func_name,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2369 char_u *arg_errmsg,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2370 typval_T *expr,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2371 typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2372 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2373 int prev_lock;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2374 list_T *l_ret = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2375 int idx = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2376 int rem;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2377 listitem_T *li, *nli;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2378 typval_T newtv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2379 funccall_T *fc;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2380
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2381 if (filtermap == FILTERMAP_MAPNEW)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2382 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2383 rettv->v_type = VAR_LIST;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2384 rettv->vval.v_list = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2385 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2386 if (l == NULL || (filtermap == FILTERMAP_FILTER
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2387 && value_check_lock(l->lv_lock, arg_errmsg, TRUE)))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2388 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2389
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2390 prev_lock = l->lv_lock;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2391
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2392 if (filtermap == FILTERMAP_MAPNEW)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2393 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2394 if (rettv_list_alloc(rettv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2395 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2396 l_ret = rettv->vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2397 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2398 // set_vim_var_nr() doesn't set the type
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2399 set_vim_var_type(VV_KEY, VAR_NUMBER);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2400
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2401 if (l->lv_lock == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2402 l->lv_lock = VAR_LOCKED;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2403
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2404 // Create one funccall_T for all eval_expr_typval() calls.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2405 fc = eval_expr_get_funccal(expr, &newtv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2406
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2407 if (l->lv_first == &range_list_item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2408 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2409 varnumber_T val = l->lv_u.nonmat.lv_start;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2410 int len = l->lv_len;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2411 int stride = l->lv_u.nonmat.lv_stride;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2412
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2413 // List from range(): loop over the numbers
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2414 if (filtermap != FILTERMAP_MAPNEW)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2415 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2416 l->lv_first = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2417 l->lv_u.mat.lv_last = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2418 l->lv_len = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2419 l->lv_u.mat.lv_idx_item = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2420 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2421
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2422 for (idx = 0; idx < len; ++idx)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2423 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2424 typval_T tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2425
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2426 tv.v_type = VAR_NUMBER;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2427 tv.v_lock = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2428 tv.vval.v_number = val;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2429 set_vim_var_nr(VV_KEY, idx);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2430 if (filter_map_one(&tv, expr, filtermap, fc, &newtv, &rem) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2431 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2432 if (did_emsg)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2433 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2434 clear_tv(&newtv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2435 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2436 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2437 if (filtermap != FILTERMAP_FILTER)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2438 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2439 if (filtermap == FILTERMAP_MAP && argtype != NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2440 && check_typval_arg_type(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2441 argtype->tt_member, &newtv,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2442 func_name, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2443 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2444 clear_tv(&newtv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2445 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2446 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2447 // map(), mapnew(): always append the new value to the
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2448 // list
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2449 if (list_append_tv_move(filtermap == FILTERMAP_MAP
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2450 ? l : l_ret, &newtv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2451 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2452 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2453 else if (!rem)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2454 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2455 // filter(): append the list item value when not rem
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2456 if (list_append_tv_move(l, &tv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2457 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2458 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2459
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2460 val += stride;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2461 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2462 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2463 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2464 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2465 // Materialized list: loop over the items
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2466 for (li = l->lv_first; li != NULL; li = nli)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2467 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2468 if (filtermap == FILTERMAP_MAP && value_check_lock(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2469 li->li_tv.v_lock, arg_errmsg, TRUE))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2470 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2471 nli = li->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2472 set_vim_var_nr(VV_KEY, idx);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2473 if (filter_map_one(&li->li_tv, expr, filtermap, fc,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2474 &newtv, &rem) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2475 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2476 if (did_emsg)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2477 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2478 clear_tv(&newtv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2479 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2480 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2481 if (filtermap == FILTERMAP_MAP)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2482 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2483 if (argtype != NULL && check_typval_arg_type(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2484 argtype->tt_member, &newtv, func_name, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2485 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2486 clear_tv(&newtv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2487 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2488 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2489 // map(): replace the list item value
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2490 clear_tv(&li->li_tv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2491 newtv.v_lock = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2492 li->li_tv = newtv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2493 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2494 else if (filtermap == FILTERMAP_MAPNEW)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2495 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2496 // mapnew(): append the list item value
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2497 if (list_append_tv_move(l_ret, &newtv) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2498 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2499 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2500 else if (filtermap == FILTERMAP_FILTER && rem)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2501 listitem_remove(l, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2502 ++idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2503 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2504 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2505
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2506 l->lv_lock = prev_lock;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2507 if (fc != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2508 remove_funccal();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2509 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2510
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2511 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2512 * Implementation of map() and filter().
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2513 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2514 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2515 filter_map(typval_T *argvars, typval_T *rettv, filtermap_T filtermap)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2516 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2517 typval_T *expr;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2518 char *func_name = filtermap == FILTERMAP_MAP ? "map()"
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2519 : filtermap == FILTERMAP_MAPNEW ? "mapnew()"
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2520 : "filter()";
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2521 char_u *arg_errmsg = (char_u *)(filtermap == FILTERMAP_MAP
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2522 ? N_("map() argument")
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2523 : filtermap == FILTERMAP_MAPNEW
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2524 ? N_("mapnew() argument")
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2525 : N_("filter() argument"));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2526 int save_did_emsg;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2527 type_T *type = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2528
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2529 // map() and filter() return the first argument, also on failure.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2530 if (filtermap != FILTERMAP_MAPNEW && argvars[0].v_type != VAR_STRING)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2531 copy_tv(&argvars[0], rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2532
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2533 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2534 && (check_for_list_or_dict_or_blob_or_string_arg(argvars, 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2535 == FAIL))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2536 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2537
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2538 if (filtermap == FILTERMAP_MAP && in_vim9script())
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2539 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2540 // Check that map() does not change the declared type of the list or
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2541 // dict.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2542 if (argvars[0].v_type == VAR_DICT && argvars[0].vval.v_dict != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2543 type = argvars[0].vval.v_dict->dv_type;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2544 else if (argvars[0].v_type == VAR_LIST
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2545 && argvars[0].vval.v_list != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2546 type = argvars[0].vval.v_list->lv_type;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2547 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2548
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2549 if (argvars[0].v_type != VAR_BLOB
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2550 && argvars[0].v_type != VAR_LIST
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2551 && argvars[0].v_type != VAR_DICT
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2552 && argvars[0].v_type != VAR_STRING)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2553 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2554 semsg(_(e_argument_of_str_must_be_list_string_dictionary_or_blob),
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2555 func_name);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2556 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2557 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2558
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2559 // On type errors, the preceding call has already displayed an error
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2560 // message. Avoid a misleading error message for an empty string that
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2561 // was not passed as argument.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2562 expr = &argvars[1];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2563 if (expr->v_type == VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2564 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2565
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2566 typval_T save_val;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2567 typval_T save_key;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2568
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2569 prepare_vimvar(VV_VAL, &save_val);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2570 prepare_vimvar(VV_KEY, &save_key);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2571
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2572 // We reset "did_emsg" to be able to detect whether an error
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2573 // occurred during evaluation of the expression.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2574 save_did_emsg = did_emsg;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2575 did_emsg = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2576
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2577 if (argvars[0].v_type == VAR_DICT)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2578 dict_filter_map(argvars[0].vval.v_dict, filtermap, type, func_name,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2579 arg_errmsg, expr, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2580 else if (argvars[0].v_type == VAR_BLOB)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2581 blob_filter_map(argvars[0].vval.v_blob, filtermap, expr,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2582 arg_errmsg, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2583 else if (argvars[0].v_type == VAR_STRING)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2584 string_filter_map(tv_get_string(&argvars[0]), filtermap, expr, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2585 else // argvars[0].v_type == VAR_LIST
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2586 list_filter_map(argvars[0].vval.v_list, filtermap, type, func_name,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2587 arg_errmsg, expr, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2588
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2589 restore_vimvar(VV_KEY, &save_key);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2590 restore_vimvar(VV_VAL, &save_val);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2591
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2592 did_emsg |= save_did_emsg;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2593 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2594
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2595 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2596 * "filter()" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2597 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2598 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2599 f_filter(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2600 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2601 filter_map(argvars, rettv, FILTERMAP_FILTER);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2602 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2603
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2604 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2605 * "map()" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2606 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2607 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2608 f_map(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2609 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2610 filter_map(argvars, rettv, FILTERMAP_MAP);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2611 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2612
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2613 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2614 * "mapnew()" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2615 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2616 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2617 f_mapnew(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2618 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2619 filter_map(argvars, rettv, FILTERMAP_MAPNEW);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2620 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2621
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2622 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2623 * "add(list, item)" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2624 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2625 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2626 list_add(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2627 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2628 list_T *l = argvars[0].vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2629
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2630 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2631 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2632 if (in_vim9script())
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2633 emsg(_(e_cannot_add_to_null_list));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2634 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2635 else if (!value_check_lock(l->lv_lock,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2636 (char_u *)N_("add() argument"), TRUE)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2637 && list_append_tv(l, &argvars[1]) == OK)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2638 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2639 copy_tv(&argvars[0], rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2640 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2641 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2642
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2643 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2644 * "add(object, item)" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2645 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2646 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2647 f_add(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2648 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2649 rettv->vval.v_number = 1; // Default: Failed
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2650
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2651 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2652 && (check_for_list_or_blob_arg(argvars, 0) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2653 || (argvars[0].v_type == VAR_BLOB
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2654 && check_for_number_arg(argvars, 1) == FAIL)))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2655 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2656
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2657 if (argvars[0].v_type == VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2658 list_add(argvars, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2659 else if (argvars[0].v_type == VAR_BLOB)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2660 blob_add(argvars, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2661 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2662 emsg(_(e_list_or_blob_required));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2663 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2664
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2665 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2666 * Count the number of times item "needle" occurs in List "l" starting at index
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2667 * "idx". Case is ignored if "ic" is TRUE.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2668 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2669 static long
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2670 list_count(list_T *l, typval_T *needle, long idx, int ic)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2671 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2672 long n = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2673 listitem_T *li;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2674
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2675 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2676 return 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2677
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2678 CHECK_LIST_MATERIALIZE(l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2679
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2680 if (list_len(l) == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2681 return 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2682
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2683 li = list_find(l, idx);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2684 if (li == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2685 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2686 semsg(_(e_list_index_out_of_range_nr), idx);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2687 return 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2688 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2689
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2690 for ( ; li != NULL; li = li->li_next)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2691 if (tv_equal(&li->li_tv, needle, ic, FALSE))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2692 ++n;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2693
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2694 return n;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2695 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2696
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2697 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2698 * "count()" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2699 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2700 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2701 f_count(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2702 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2703 long n = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2704 int ic = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2705 int error = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2706
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2707 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2708 && (check_for_string_or_list_or_dict_arg(argvars, 0) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2709 || check_for_opt_bool_arg(argvars, 2) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2710 || (argvars[2].v_type != VAR_UNKNOWN
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2711 && check_for_opt_number_arg(argvars, 3) == FAIL)))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2712 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2713
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2714 if (argvars[2].v_type != VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2715 ic = (int)tv_get_bool_chk(&argvars[2], &error);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2716
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2717 if (!error && argvars[0].v_type == VAR_STRING)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2718 n = string_count(argvars[0].vval.v_string,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2719 tv_get_string_chk(&argvars[1]), ic);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2720 else if (!error && argvars[0].v_type == VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2721 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2722 long idx = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2723
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2724 if (argvars[2].v_type != VAR_UNKNOWN
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2725 && argvars[3].v_type != VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2726 idx = (long)tv_get_number_chk(&argvars[3], &error);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2727 if (!error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2728 n = list_count(argvars[0].vval.v_list, &argvars[1], idx, ic);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2729 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2730 else if (!error && argvars[0].v_type == VAR_DICT)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2731 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2732 if (argvars[2].v_type != VAR_UNKNOWN
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2733 && argvars[3].v_type != VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2734 emsg(_(e_invalid_argument));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2735 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2736 n = dict_count(argvars[0].vval.v_dict, &argvars[1], ic);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2737 }
32816
939396a5711c patch 9.0.1722: wrong error messages when passing wrong types to count()
Christian Brabandt <cb@256bit.org>
parents: 32670
diff changeset
2738 else if (!error)
939396a5711c patch 9.0.1722: wrong error messages when passing wrong types to count()
Christian Brabandt <cb@256bit.org>
parents: 32670
diff changeset
2739 semsg(_(e_argument_of_str_must_be_list_string_or_dictionary),
939396a5711c patch 9.0.1722: wrong error messages when passing wrong types to count()
Christian Brabandt <cb@256bit.org>
parents: 32670
diff changeset
2740 "count()");
32670
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2741 rettv->vval.v_number = n;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2742 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2743
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2744 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2745 * extend() a List. Append List argvars[1] to List argvars[0] before index
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2746 * argvars[3] and return the resulting list in "rettv". "is_new" is TRUE for
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2747 * extendnew().
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2748 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2749 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2750 list_extend_func(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2751 typval_T *argvars,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2752 type_T *type,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2753 char *func_name,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2754 char_u *arg_errmsg,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2755 int is_new,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2756 typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2757 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2758 list_T *l1, *l2;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2759 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2760 long before;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2761 int error = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2762
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2763 l1 = argvars[0].vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2764 if (l1 == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2765 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2766 emsg(_(e_cannot_extend_null_list));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2767 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2768 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2769 l2 = argvars[1].vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2770 if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2771 && l2 != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2772 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2773 if (is_new)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2774 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2775 l1 = list_copy(l1, FALSE, TRUE, get_copyID());
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2776 if (l1 == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2777 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2778 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2779
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2780 if (argvars[2].v_type != VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2781 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2782 before = (long)tv_get_number_chk(&argvars[2], &error);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2783 if (error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2784 return; // type error; errmsg already given
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2785
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2786 if (before == l1->lv_len)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2787 item = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2788 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2789 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2790 item = list_find(l1, before);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2791 if (item == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2792 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2793 semsg(_(e_list_index_out_of_range_nr), before);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2794 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2795 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2796 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2797 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2798 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2799 item = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2800 if (type != NULL && check_typval_arg_type(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2801 type, &argvars[1], func_name, 2) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2802 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2803 list_extend(l1, l2, item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2804
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2805 if (is_new)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2806 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2807 rettv->v_type = VAR_LIST;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2808 rettv->vval.v_list = l1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2809 rettv->v_lock = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2810 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2811 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2812 copy_tv(&argvars[0], rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2813 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2814 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2815
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2816 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2817 * "extend()" or "extendnew()" function. "is_new" is TRUE for extendnew().
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2818 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2819 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2820 extend(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg, int is_new)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2821 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2822 type_T *type = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2823 char *func_name = is_new ? "extendnew()" : "extend()";
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2824
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2825 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2826 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2827 // Check that extend() does not change the type of the list if it was
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2828 // declared.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2829 if (!is_new && in_vim9script() && argvars[0].vval.v_list != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2830 type = argvars[0].vval.v_list->lv_type;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2831 list_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2832 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2833 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2834 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2835 // Check that extend() does not change the type of the dict if it was
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2836 // declared.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2837 if (!is_new && in_vim9script() && argvars[0].vval.v_dict != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2838 type = argvars[0].vval.v_dict->dv_type;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2839 dict_extend_func(argvars, type, func_name, arg_errmsg, is_new, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2840 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2841 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2842 semsg(_(e_argument_of_str_must_be_list_or_dictionary), func_name);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2843 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2844
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2845 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2846 * "extend(list, list [, idx])" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2847 * "extend(dict, dict [, action])" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2848 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2849 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2850 f_extend(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2851 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2852 char_u *errmsg = (char_u *)N_("extend() argument");
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2853
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2854 extend(argvars, rettv, errmsg, FALSE);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2855 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2856
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2857 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2858 * "extendnew(list, list [, idx])" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2859 * "extendnew(dict, dict [, action])" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2860 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2861 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2862 f_extendnew(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2863 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2864 char_u *errmsg = (char_u *)N_("extendnew() argument");
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2865
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2866 extend(argvars, rettv, errmsg, TRUE);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2867 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2868
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2869 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2870 list_insert_func(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2871 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2872 list_T *l = argvars[0].vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2873 long before = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2874 listitem_T *item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2875 int error = FALSE;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2876
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2877 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2878 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2879 if (in_vim9script())
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2880 emsg(_(e_cannot_add_to_null_list));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2881 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2882 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2883
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2884 if (value_check_lock(l->lv_lock, (char_u *)N_("insert() argument"), TRUE))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2885 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2886
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2887 if (argvars[2].v_type != VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2888 before = (long)tv_get_number_chk(&argvars[2], &error);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2889 if (error)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2890 return; // type error; errmsg already given
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2891
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2892 if (before == l->lv_len)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2893 item = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2894 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2895 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2896 item = list_find(l, before);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2897 if (item == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2898 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2899 semsg(_(e_list_index_out_of_range_nr), before);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2900 l = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2901 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2902 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2903 if (l != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2904 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2905 (void)list_insert_tv(l, &argvars[1], item);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2906 copy_tv(&argvars[0], rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2907 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2908 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2909
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2910 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2911 * "insert()" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2912 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2913 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2914 f_insert(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2915 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2916 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2917 && (check_for_list_or_blob_arg(argvars, 0) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2918 || (argvars[0].v_type == VAR_BLOB
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2919 && check_for_number_arg(argvars, 1) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2920 || check_for_opt_number_arg(argvars, 2) == FAIL))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2921 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2922
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2923 if (argvars[0].v_type == VAR_BLOB)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2924 blob_insert_func(argvars, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2925 else if (argvars[0].v_type != VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2926 semsg(_(e_argument_of_str_must_be_list_or_blob), "insert()");
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2927 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2928 list_insert_func(argvars, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2929 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2930
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2931 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2932 * "remove()" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2933 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2934 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2935 f_remove(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2936 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2937 char_u *arg_errmsg = (char_u *)N_("remove() argument");
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2938
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2939 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2940 && (check_for_list_or_dict_or_blob_arg(argvars, 0) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2941 || ((argvars[0].v_type == VAR_LIST
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2942 || argvars[0].v_type == VAR_BLOB)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2943 && (check_for_number_arg(argvars, 1) == FAIL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2944 || check_for_opt_number_arg(argvars, 2) == FAIL))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2945 || (argvars[0].v_type == VAR_DICT
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2946 && check_for_string_or_number_arg(argvars, 1) == FAIL)))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2947 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2948
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2949 if (argvars[0].v_type == VAR_DICT)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2950 dict_remove(argvars, rettv, arg_errmsg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2951 else if (argvars[0].v_type == VAR_BLOB)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2952 blob_remove(argvars, rettv, arg_errmsg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2953 else if (argvars[0].v_type == VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2954 list_remove(argvars, rettv, arg_errmsg);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2955 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2956 semsg(_(e_argument_of_str_must_be_list_dictionary_or_blob), "remove()");
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2957 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2958
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2959 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2960 list_reverse(list_T *l, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2961 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2962 listitem_T *li, *ni;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2963
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2964 rettv_list_set(rettv, l);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2965 if (l != NULL
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2966 && !value_check_lock(l->lv_lock,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2967 (char_u *)N_("reverse() argument"), TRUE))
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2968 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2969 if (l->lv_first == &range_list_item)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2970 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2971 varnumber_T new_start = l->lv_u.nonmat.lv_start
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2972 + ((varnumber_T)l->lv_len - 1) * l->lv_u.nonmat.lv_stride;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2973 l->lv_u.nonmat.lv_end = new_start
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2974 - (l->lv_u.nonmat.lv_end - l->lv_u.nonmat.lv_start);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2975 l->lv_u.nonmat.lv_start = new_start;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2976 l->lv_u.nonmat.lv_stride = -l->lv_u.nonmat.lv_stride;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2977 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2978 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2979 li = l->lv_u.mat.lv_last;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2980 l->lv_first = l->lv_u.mat.lv_last = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2981 l->lv_len = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2982 while (li != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2983 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2984 ni = li->li_prev;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2985 list_append(l, li);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2986 li = ni;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2987 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2988 l->lv_u.mat.lv_idx = l->lv_len - l->lv_u.mat.lv_idx - 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2989 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2990 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2991
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2992 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2993 * "reverse({list})" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2994 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2995 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2996 f_reverse(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2997 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2998 if (check_for_string_or_list_or_blob_arg(argvars, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
2999 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3000
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3001 if (argvars[0].v_type == VAR_BLOB)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3002 blob_reverse(argvars[0].vval.v_blob, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3003 else if (argvars[0].v_type == VAR_STRING)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3004 string_reverse(argvars[0].vval.v_string, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3005 else if (argvars[0].v_type == VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3006 list_reverse(argvars[0].vval.v_list, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3007 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3008
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3009 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3010 * Implementation of reduce() for list "argvars[0]", using the function "expr"
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3011 * starting with the optional initial value argvars[2] and return the result in
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3012 * "rettv".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3013 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3014 static void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3015 list_reduce(
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3016 typval_T *argvars,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3017 typval_T *expr,
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3018 typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3019 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3020 list_T *l = argvars[0].vval.v_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3021 listitem_T *li = NULL;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3022 int range_list;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3023 int range_idx = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3024 varnumber_T range_val = 0;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3025 typval_T initial;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3026 typval_T argv[3];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3027 int r;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3028 int called_emsg_start = called_emsg;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3029 int prev_locked;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3030 funccall_T *fc;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3031
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3032 // Using reduce on a range() uses "range_idx" and "range_val".
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3033 range_list = l != NULL && l->lv_first == &range_list_item;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3034 if (range_list)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3035 range_val = l->lv_u.nonmat.lv_start;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3036
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3037 if (argvars[2].v_type == VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3038 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3039 if (l == NULL || l->lv_len == 0)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3040 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3041 semsg(_(e_reduce_of_an_empty_str_with_no_initial_value), "List");
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3042 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3043 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3044 if (range_list)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3045 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3046 initial.v_type = VAR_NUMBER;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3047 initial.vval.v_number = range_val;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3048 range_val += l->lv_u.nonmat.lv_stride;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3049 range_idx = 1;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3050 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3051 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3052 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3053 initial = l->lv_first->li_tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3054 li = l->lv_first->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3055 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3056 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3057 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3058 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3059 initial = argvars[2];
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3060 if (l != NULL && !range_list)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3061 li = l->lv_first;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3062 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3063 copy_tv(&initial, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3064
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3065 if (l == NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3066 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3067
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3068 // Create one funccall_T for all eval_expr_typval() calls.
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3069 fc = eval_expr_get_funccal(expr, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3070
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3071 prev_locked = l->lv_lock;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3072 l->lv_lock = VAR_FIXED; // disallow the list changing here
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3073
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3074 while (range_list ? range_idx < l->lv_len : li != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3075 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3076 argv[0] = *rettv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3077 rettv->v_type = VAR_UNKNOWN;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3078
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3079 if (range_list)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3080 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3081 argv[1].v_type = VAR_NUMBER;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3082 argv[1].vval.v_number = range_val;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3083 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3084 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3085 argv[1] = li->li_tv;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3086
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3087 r = eval_expr_typval(expr, argv, 2, fc, rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3088
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3089 if (argv[0].v_type != VAR_NUMBER && argv[0].v_type != VAR_UNKNOWN)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3090 clear_tv(&argv[0]);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3091 if (r == FAIL || called_emsg != called_emsg_start)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3092 break;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3093
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3094 // advance to the next item
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3095 if (range_list)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3096 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3097 range_val += l->lv_u.nonmat.lv_stride;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3098 ++range_idx;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3099 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3100 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3101 li = li->li_next;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3102 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3103
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3104 if (fc != NULL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3105 remove_funccal();
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3106
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3107 l->lv_lock = prev_locked;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3108 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3109
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3110 /*
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3111 * "reduce(list, { accumulator, element -> value } [, initial])" function
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3112 * "reduce(blob, { accumulator, element -> value } [, initial])"
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3113 * "reduce(string, { accumulator, element -> value } [, initial])"
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3114 */
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3115 void
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3116 f_reduce(typval_T *argvars, typval_T *rettv)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3117 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3118 char_u *func_name;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3119
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3120 if (in_vim9script()
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3121 && check_for_string_or_list_or_blob_arg(argvars, 0) == FAIL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3122 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3123
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3124 if (argvars[0].v_type != VAR_STRING
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3125 && argvars[0].v_type != VAR_LIST
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3126 && argvars[0].v_type != VAR_BLOB)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3127 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3128 semsg(_(e_string_list_or_blob_required), "reduce()");
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3129 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3130 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3131
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3132 if (argvars[1].v_type == VAR_FUNC)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3133 func_name = argvars[1].vval.v_string;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3134 else if (argvars[1].v_type == VAR_PARTIAL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3135 func_name = partial_name(argvars[1].vval.v_partial);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3136 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3137 func_name = tv_get_string(&argvars[1]);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3138 if (func_name == NULL || *func_name == NUL)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3139 {
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3140 emsg(_(e_missing_function_argument));
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3141 return;
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3142 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3143
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3144 if (argvars[0].v_type == VAR_LIST)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3145 list_reduce(argvars, &argvars[1], rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3146 else if (argvars[0].v_type == VAR_STRING)
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3147 string_reduce(argvars, &argvars[1], rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3148 else
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3149 blob_reduce(argvars, &argvars[1], rettv);
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3150 }
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3151
695b50472e85 Fix line endings issue
Christian Brabandt <cb@256bit.org>
parents: 32669
diff changeset
3152 #endif // defined(FEAT_EVAL)