]>
Commit | Line | Data |
---|---|---|
ac3d33df JK |
1 | #include <stdint.h> |
2 | ||
3fd1520c | 3 | #include "clar_libgit2.h" |
f1558d9b VM |
4 | #include "vector.h" |
5 | ||
6 | /* initial size of 1 would cause writing past array bounds */ | |
7 | void test_core_vector__0(void) | |
8 | { | |
9 | git_vector x; | |
10 | int i; | |
c25aa7cd | 11 | cl_git_pass(git_vector_init(&x, 1, NULL)); |
f1558d9b VM |
12 | for (i = 0; i < 10; ++i) { |
13 | git_vector_insert(&x, (void*) 0xabc); | |
14 | } | |
15 | git_vector_free(&x); | |
16 | } | |
17 | ||
18 | ||
19 | /* don't read past array bounds on remove() */ | |
20 | void test_core_vector__1(void) | |
21 | { | |
22 | git_vector x; | |
ac3d33df | 23 | /* make initial capacity exact for our insertions. */ |
c25aa7cd | 24 | cl_git_pass(git_vector_init(&x, 3, NULL)); |
f1558d9b VM |
25 | git_vector_insert(&x, (void*) 0xabc); |
26 | git_vector_insert(&x, (void*) 0xdef); | |
27 | git_vector_insert(&x, (void*) 0x123); | |
28 | ||
ac3d33df | 29 | git_vector_remove(&x, 0); /* used to read past array bounds. */ |
f1558d9b VM |
30 | git_vector_free(&x); |
31 | } | |
32 | ||
33 | ||
34 | static int test_cmp(const void *a, const void *b) | |
35 | { | |
36 | return *(const int *)a - *(const int *)b; | |
37 | } | |
38 | ||
39 | /* remove duplicates */ | |
40 | void test_core_vector__2(void) | |
41 | { | |
42 | git_vector x; | |
43 | int *ptrs[2]; | |
44 | ||
45 | ptrs[0] = git__malloc(sizeof(int)); | |
46 | ptrs[1] = git__malloc(sizeof(int)); | |
47 | ||
48 | *ptrs[0] = 2; | |
49 | *ptrs[1] = 1; | |
50 | ||
51 | cl_git_pass(git_vector_init(&x, 5, test_cmp)); | |
52 | cl_git_pass(git_vector_insert(&x, ptrs[0])); | |
53 | cl_git_pass(git_vector_insert(&x, ptrs[1])); | |
54 | cl_git_pass(git_vector_insert(&x, ptrs[1])); | |
55 | cl_git_pass(git_vector_insert(&x, ptrs[0])); | |
56 | cl_git_pass(git_vector_insert(&x, ptrs[1])); | |
57 | cl_assert(x.length == 5); | |
58 | ||
191adce8 | 59 | git_vector_uniq(&x, NULL); |
f1558d9b VM |
60 | cl_assert(x.length == 2); |
61 | ||
62 | git_vector_free(&x); | |
63 | ||
3286c408 VM |
64 | git__free(ptrs[0]); |
65 | git__free(ptrs[1]); | |
f1558d9b VM |
66 | } |
67 | ||
68 | ||
bd370b14 RB |
69 | static int compare_them(const void *a, const void *b) |
70 | { | |
ac3d33df | 71 | return (int)((intptr_t)a - (intptr_t)b); |
bd370b14 RB |
72 | } |
73 | ||
74 | /* insert_sorted */ | |
75 | void test_core_vector__3(void) | |
76 | { | |
77 | git_vector x; | |
ac3d33df | 78 | intptr_t i; |
c25aa7cd | 79 | cl_git_pass(git_vector_init(&x, 1, &compare_them)); |
bd370b14 RB |
80 | |
81 | for (i = 0; i < 10; i += 2) { | |
82 | git_vector_insert_sorted(&x, (void*)(i + 1), NULL); | |
83 | } | |
84 | ||
85 | for (i = 9; i > 0; i -= 2) { | |
86 | git_vector_insert_sorted(&x, (void*)(i + 1), NULL); | |
87 | } | |
88 | ||
89 | cl_assert(x.length == 10); | |
90 | for (i = 0; i < 10; ++i) { | |
91 | cl_assert(git_vector_get(&x, i) == (void*)(i + 1)); | |
92 | } | |
93 | ||
94 | git_vector_free(&x); | |
95 | } | |
96 | ||
97 | /* insert_sorted with duplicates */ | |
98 | void test_core_vector__4(void) | |
99 | { | |
100 | git_vector x; | |
ac3d33df | 101 | intptr_t i; |
c25aa7cd | 102 | cl_git_pass(git_vector_init(&x, 1, &compare_them)); |
bd370b14 RB |
103 | |
104 | for (i = 0; i < 10; i += 2) { | |
105 | git_vector_insert_sorted(&x, (void*)(i + 1), NULL); | |
106 | } | |
107 | ||
108 | for (i = 9; i > 0; i -= 2) { | |
109 | git_vector_insert_sorted(&x, (void*)(i + 1), NULL); | |
110 | } | |
111 | ||
112 | for (i = 0; i < 10; i += 2) { | |
113 | git_vector_insert_sorted(&x, (void*)(i + 1), NULL); | |
114 | } | |
115 | ||
116 | for (i = 9; i > 0; i -= 2) { | |
117 | git_vector_insert_sorted(&x, (void*)(i + 1), NULL); | |
118 | } | |
119 | ||
120 | cl_assert(x.length == 20); | |
121 | for (i = 0; i < 20; ++i) { | |
122 | cl_assert(git_vector_get(&x, i) == (void*)(i / 2 + 1)); | |
123 | } | |
124 | ||
125 | git_vector_free(&x); | |
126 | } | |
127 | ||
128 | typedef struct { | |
129 | int content; | |
130 | int count; | |
131 | } my_struct; | |
132 | ||
133 | static int _struct_count = 0; | |
134 | ||
135 | static int compare_structs(const void *a, const void *b) | |
136 | { | |
137 | return ((const my_struct *)a)->content - | |
138 | ((const my_struct *)b)->content; | |
139 | } | |
140 | ||
141 | static int merge_structs(void **old_raw, void *new) | |
142 | { | |
143 | my_struct *old = *(my_struct **)old_raw; | |
144 | cl_assert(((my_struct *)old)->content == ((my_struct *)new)->content); | |
145 | ((my_struct *)old)->count += 1; | |
146 | git__free(new); | |
147 | _struct_count--; | |
148 | return GIT_EEXISTS; | |
149 | } | |
150 | ||
151 | static my_struct *alloc_struct(int value) | |
152 | { | |
153 | my_struct *st = git__malloc(sizeof(my_struct)); | |
154 | st->content = value; | |
155 | st->count = 0; | |
156 | _struct_count++; | |
157 | return st; | |
158 | } | |
159 | ||
160 | /* insert_sorted with duplicates and special handling */ | |
161 | void test_core_vector__5(void) | |
162 | { | |
163 | git_vector x; | |
164 | int i; | |
165 | ||
c25aa7cd | 166 | cl_git_pass(git_vector_init(&x, 1, &compare_structs)); |
bd370b14 RB |
167 | |
168 | for (i = 0; i < 10; i += 2) | |
169 | git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs); | |
170 | ||
171 | for (i = 9; i > 0; i -= 2) | |
172 | git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs); | |
173 | ||
174 | cl_assert(x.length == 10); | |
175 | cl_assert(_struct_count == 10); | |
176 | ||
177 | for (i = 0; i < 10; i += 2) | |
178 | git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs); | |
179 | ||
180 | for (i = 9; i > 0; i -= 2) | |
181 | git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs); | |
182 | ||
183 | cl_assert(x.length == 10); | |
184 | cl_assert(_struct_count == 10); | |
185 | ||
186 | for (i = 0; i < 10; ++i) { | |
187 | cl_assert(((my_struct *)git_vector_get(&x, i))->content == i); | |
188 | git__free(git_vector_get(&x, i)); | |
189 | _struct_count--; | |
190 | } | |
191 | ||
192 | git_vector_free(&x); | |
193 | } | |
f45ec1a0 | 194 | |
c67fd4c9 | 195 | static int remove_ones(const git_vector *v, size_t idx, void *p) |
f45ec1a0 | 196 | { |
c67fd4c9 | 197 | GIT_UNUSED(p); |
f45ec1a0 ET |
198 | return (git_vector_get(v, idx) == (void *)0x001); |
199 | } | |
200 | ||
201 | /* Test removal based on callback */ | |
202 | void test_core_vector__remove_matching(void) | |
203 | { | |
204 | git_vector x; | |
205 | size_t i; | |
206 | void *compare; | |
207 | ||
c25aa7cd | 208 | cl_git_pass(git_vector_init(&x, 1, NULL)); |
f45ec1a0 ET |
209 | git_vector_insert(&x, (void*) 0x001); |
210 | ||
211 | cl_assert(x.length == 1); | |
c67fd4c9 | 212 | git_vector_remove_matching(&x, remove_ones, NULL); |
f45ec1a0 ET |
213 | cl_assert(x.length == 0); |
214 | ||
215 | git_vector_insert(&x, (void*) 0x001); | |
216 | git_vector_insert(&x, (void*) 0x001); | |
217 | git_vector_insert(&x, (void*) 0x001); | |
218 | ||
219 | cl_assert(x.length == 3); | |
c67fd4c9 | 220 | git_vector_remove_matching(&x, remove_ones, NULL); |
f45ec1a0 ET |
221 | cl_assert(x.length == 0); |
222 | ||
223 | git_vector_insert(&x, (void*) 0x002); | |
224 | git_vector_insert(&x, (void*) 0x001); | |
225 | git_vector_insert(&x, (void*) 0x002); | |
226 | git_vector_insert(&x, (void*) 0x001); | |
227 | ||
228 | cl_assert(x.length == 4); | |
c67fd4c9 | 229 | git_vector_remove_matching(&x, remove_ones, NULL); |
f45ec1a0 ET |
230 | cl_assert(x.length == 2); |
231 | ||
232 | git_vector_foreach(&x, i, compare) { | |
233 | cl_assert(compare != (void *)0x001); | |
234 | } | |
235 | ||
236 | git_vector_clear(&x); | |
237 | ||
238 | git_vector_insert(&x, (void*) 0x001); | |
239 | git_vector_insert(&x, (void*) 0x002); | |
240 | git_vector_insert(&x, (void*) 0x002); | |
241 | git_vector_insert(&x, (void*) 0x001); | |
242 | ||
243 | cl_assert(x.length == 4); | |
c67fd4c9 | 244 | git_vector_remove_matching(&x, remove_ones, NULL); |
f45ec1a0 ET |
245 | cl_assert(x.length == 2); |
246 | ||
247 | git_vector_foreach(&x, i, compare) { | |
248 | cl_assert(compare != (void *)0x001); | |
249 | } | |
250 | ||
251 | git_vector_clear(&x); | |
252 | ||
253 | git_vector_insert(&x, (void*) 0x002); | |
254 | git_vector_insert(&x, (void*) 0x001); | |
255 | git_vector_insert(&x, (void*) 0x002); | |
256 | git_vector_insert(&x, (void*) 0x001); | |
257 | ||
258 | cl_assert(x.length == 4); | |
c67fd4c9 | 259 | git_vector_remove_matching(&x, remove_ones, NULL); |
f45ec1a0 ET |
260 | cl_assert(x.length == 2); |
261 | ||
262 | git_vector_foreach(&x, i, compare) { | |
263 | cl_assert(compare != (void *)0x001); | |
264 | } | |
265 | ||
266 | git_vector_clear(&x); | |
267 | ||
268 | git_vector_insert(&x, (void*) 0x002); | |
269 | git_vector_insert(&x, (void*) 0x003); | |
270 | git_vector_insert(&x, (void*) 0x002); | |
271 | git_vector_insert(&x, (void*) 0x003); | |
272 | ||
273 | cl_assert(x.length == 4); | |
c67fd4c9 | 274 | git_vector_remove_matching(&x, remove_ones, NULL); |
f45ec1a0 ET |
275 | cl_assert(x.length == 4); |
276 | ||
277 | git_vector_free(&x); | |
278 | } | |
e564fc65 ET |
279 | |
280 | static void assert_vector(git_vector *x, void *expected[], size_t len) | |
281 | { | |
282 | size_t i; | |
283 | ||
284 | cl_assert_equal_i(len, x->length); | |
285 | ||
286 | for (i = 0; i < len; i++) | |
287 | cl_assert(expected[i] == x->contents[i]); | |
288 | } | |
289 | ||
290 | void test_core_vector__grow_and_shrink(void) | |
291 | { | |
292 | git_vector x = GIT_VECTOR_INIT; | |
293 | void *expected1[] = { | |
294 | (void *)0x02, (void *)0x03, (void *)0x04, (void *)0x05, | |
295 | (void *)0x06, (void *)0x07, (void *)0x08, (void *)0x09, | |
296 | (void *)0x0a | |
297 | }; | |
298 | void *expected2[] = { | |
299 | (void *)0x02, (void *)0x04, (void *)0x05, (void *)0x06, | |
300 | (void *)0x07, (void *)0x08, (void *)0x09, (void *)0x0a | |
301 | }; | |
302 | void *expected3[] = { | |
303 | (void *)0x02, (void *)0x04, (void *)0x05, (void *)0x06, | |
304 | (void *)0x0a | |
305 | }; | |
306 | void *expected4[] = { | |
307 | (void *)0x02, (void *)0x04, (void *)0x05 | |
308 | }; | |
309 | void *expected5[] = { | |
310 | (void *)0x00, (void *)0x00, (void *)0x02, (void *)0x04, | |
311 | (void *)0x05 | |
312 | }; | |
313 | void *expected6[] = { | |
314 | (void *)0x00, (void *)0x00, (void *)0x02, (void *)0x04, | |
315 | (void *)0x05, (void *)0x00 | |
316 | }; | |
317 | void *expected7[] = { | |
318 | (void *)0x00, (void *)0x00, (void *)0x02, (void *)0x04, | |
319 | (void *)0x00, (void *)0x00, (void *)0x00, (void *)0x05, | |
320 | (void *)0x00 | |
321 | }; | |
322 | void *expected8[] = { | |
323 | (void *)0x04, (void *)0x00, (void *)0x00, (void *)0x00, | |
324 | (void *)0x05, (void *)0x00 | |
325 | }; | |
326 | void *expected9[] = { | |
327 | (void *)0x04, (void *)0x00, (void *)0x05, (void *)0x00 | |
328 | }; | |
329 | void *expectedA[] = { (void *)0x04, (void *)0x00 }; | |
330 | void *expectedB[] = { (void *)0x04 }; | |
331 | ||
332 | git_vector_insert(&x, (void *)0x01); | |
333 | git_vector_insert(&x, (void *)0x02); | |
334 | git_vector_insert(&x, (void *)0x03); | |
335 | git_vector_insert(&x, (void *)0x04); | |
336 | git_vector_insert(&x, (void *)0x05); | |
337 | git_vector_insert(&x, (void *)0x06); | |
338 | git_vector_insert(&x, (void *)0x07); | |
339 | git_vector_insert(&x, (void *)0x08); | |
340 | git_vector_insert(&x, (void *)0x09); | |
341 | git_vector_insert(&x, (void *)0x0a); | |
342 | ||
53571f2f | 343 | git_vector_remove_range(&x, 0, 1); |
e564fc65 ET |
344 | assert_vector(&x, expected1, ARRAY_SIZE(expected1)); |
345 | ||
53571f2f | 346 | git_vector_remove_range(&x, 1, 1); |
e564fc65 ET |
347 | assert_vector(&x, expected2, ARRAY_SIZE(expected2)); |
348 | ||
53571f2f | 349 | git_vector_remove_range(&x, 4, 3); |
e564fc65 ET |
350 | assert_vector(&x, expected3, ARRAY_SIZE(expected3)); |
351 | ||
53571f2f | 352 | git_vector_remove_range(&x, 3, 2); |
e564fc65 ET |
353 | assert_vector(&x, expected4, ARRAY_SIZE(expected4)); |
354 | ||
53571f2f | 355 | git_vector_insert_null(&x, 0, 2); |
e564fc65 ET |
356 | assert_vector(&x, expected5, ARRAY_SIZE(expected5)); |
357 | ||
53571f2f | 358 | git_vector_insert_null(&x, 5, 1); |
e564fc65 ET |
359 | assert_vector(&x, expected6, ARRAY_SIZE(expected6)); |
360 | ||
53571f2f | 361 | git_vector_insert_null(&x, 4, 3); |
e564fc65 ET |
362 | assert_vector(&x, expected7, ARRAY_SIZE(expected7)); |
363 | ||
53571f2f | 364 | git_vector_remove_range(&x, 0, 3); |
e564fc65 ET |
365 | assert_vector(&x, expected8, ARRAY_SIZE(expected8)); |
366 | ||
53571f2f | 367 | git_vector_remove_range(&x, 1, 2); |
e564fc65 ET |
368 | assert_vector(&x, expected9, ARRAY_SIZE(expected9)); |
369 | ||
53571f2f | 370 | git_vector_remove_range(&x, 2, 2); |
e564fc65 ET |
371 | assert_vector(&x, expectedA, ARRAY_SIZE(expectedA)); |
372 | ||
53571f2f | 373 | git_vector_remove_range(&x, 1, 1); |
e564fc65 ET |
374 | assert_vector(&x, expectedB, ARRAY_SIZE(expectedB)); |
375 | ||
53571f2f | 376 | git_vector_remove_range(&x, 0, 1); |
e564fc65 ET |
377 | assert_vector(&x, NULL, 0); |
378 | ||
379 | git_vector_free(&x); | |
380 | } | |
0bd43371 CMN |
381 | |
382 | void test_core_vector__reverse(void) | |
383 | { | |
384 | git_vector v = GIT_VECTOR_INIT; | |
385 | size_t i; | |
386 | ||
387 | void *in1[] = {(void *) 0x0, (void *) 0x1, (void *) 0x2, (void *) 0x3}; | |
388 | void *out1[] = {(void *) 0x3, (void *) 0x2, (void *) 0x1, (void *) 0x0}; | |
389 | ||
390 | void *in2[] = {(void *) 0x0, (void *) 0x1, (void *) 0x2, (void *) 0x3, (void *) 0x4}; | |
391 | void *out2[] = {(void *) 0x4, (void *) 0x3, (void *) 0x2, (void *) 0x1, (void *) 0x0}; | |
392 | ||
393 | for (i = 0; i < 4; i++) | |
394 | cl_git_pass(git_vector_insert(&v, in1[i])); | |
395 | ||
396 | git_vector_reverse(&v); | |
397 | ||
398 | for (i = 0; i < 4; i++) | |
399 | cl_assert_equal_p(out1[i], git_vector_get(&v, i)); | |
400 | ||
401 | git_vector_clear(&v); | |
402 | for (i = 0; i < 5; i++) | |
403 | cl_git_pass(git_vector_insert(&v, in2[i])); | |
404 | ||
405 | git_vector_reverse(&v); | |
406 | ||
407 | for (i = 0; i < 5; i++) | |
408 | cl_assert_equal_p(out2[i], git_vector_get(&v, i)); | |
61ad9bcd PS |
409 | |
410 | git_vector_free(&v); | |
0bd43371 | 411 | } |
6c7cee42 RD |
412 | |
413 | void test_core_vector__dup_empty_vector(void) | |
414 | { | |
415 | git_vector v = GIT_VECTOR_INIT; | |
416 | git_vector dup = GIT_VECTOR_INIT; | |
417 | int dummy; | |
418 | ||
419 | cl_assert_equal_i(0, v.length); | |
420 | ||
421 | cl_git_pass(git_vector_dup(&dup, &v, v._cmp)); | |
422 | cl_assert_equal_i(0, dup._alloc_size); | |
423 | cl_assert_equal_i(0, dup.length); | |
424 | ||
425 | cl_git_pass(git_vector_insert(&dup, &dummy)); | |
426 | cl_assert_equal_i(8, dup._alloc_size); | |
427 | cl_assert_equal_i(1, dup.length); | |
428 | ||
429 | git_vector_free(&dup); | |
430 | } |