]> git.proxmox.com Git - libgit2.git/blame - tests/core/vector.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / tests / core / vector.c
CommitLineData
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 */
7void 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() */
20void 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
34static int test_cmp(const void *a, const void *b)
35{
36 return *(const int *)a - *(const int *)b;
37}
38
39/* remove duplicates */
40void 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
69static 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 */
75void 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 */
98void 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
128typedef struct {
129 int content;
130 int count;
131} my_struct;
132
133static int _struct_count = 0;
134
135static 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
141static 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
151static 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 */
161void 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 195static 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 */
202void 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
280static 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
290void 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
382void 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
413void 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}