| #include "clar_libgit2.h" |
| #include "vector.h" |
| |
| /* initial size of 1 would cause writing past array bounds */ |
| void test_core_vector__0(void) |
| { |
| git_vector x; |
| int i; |
| git_vector_init(&x, 1, NULL); |
| for (i = 0; i < 10; ++i) { |
| git_vector_insert(&x, (void*) 0xabc); |
| } |
| git_vector_free(&x); |
| } |
| |
| |
| /* don't read past array bounds on remove() */ |
| void test_core_vector__1(void) |
| { |
| git_vector x; |
| // make initial capacity exact for our insertions. |
| git_vector_init(&x, 3, NULL); |
| git_vector_insert(&x, (void*) 0xabc); |
| git_vector_insert(&x, (void*) 0xdef); |
| git_vector_insert(&x, (void*) 0x123); |
| |
| git_vector_remove(&x, 0); // used to read past array bounds. |
| git_vector_free(&x); |
| } |
| |
| |
| static int test_cmp(const void *a, const void *b) |
| { |
| return *(const int *)a - *(const int *)b; |
| } |
| |
| /* remove duplicates */ |
| void test_core_vector__2(void) |
| { |
| git_vector x; |
| int *ptrs[2]; |
| |
| ptrs[0] = git__malloc(sizeof(int)); |
| ptrs[1] = git__malloc(sizeof(int)); |
| |
| *ptrs[0] = 2; |
| *ptrs[1] = 1; |
| |
| cl_git_pass(git_vector_init(&x, 5, test_cmp)); |
| cl_git_pass(git_vector_insert(&x, ptrs[0])); |
| cl_git_pass(git_vector_insert(&x, ptrs[1])); |
| cl_git_pass(git_vector_insert(&x, ptrs[1])); |
| cl_git_pass(git_vector_insert(&x, ptrs[0])); |
| cl_git_pass(git_vector_insert(&x, ptrs[1])); |
| cl_assert(x.length == 5); |
| |
| git_vector_uniq(&x); |
| cl_assert(x.length == 2); |
| |
| git_vector_free(&x); |
| |
| git__free(ptrs[0]); |
| git__free(ptrs[1]); |
| } |
| |
| |
| static int compare_them(const void *a, const void *b) |
| { |
| return (int)((long)a - (long)b); |
| } |
| |
| /* insert_sorted */ |
| void test_core_vector__3(void) |
| { |
| git_vector x; |
| long i; |
| git_vector_init(&x, 1, &compare_them); |
| |
| for (i = 0; i < 10; i += 2) { |
| git_vector_insert_sorted(&x, (void*)(i + 1), NULL); |
| } |
| |
| for (i = 9; i > 0; i -= 2) { |
| git_vector_insert_sorted(&x, (void*)(i + 1), NULL); |
| } |
| |
| cl_assert(x.length == 10); |
| for (i = 0; i < 10; ++i) { |
| cl_assert(git_vector_get(&x, i) == (void*)(i + 1)); |
| } |
| |
| git_vector_free(&x); |
| } |
| |
| /* insert_sorted with duplicates */ |
| void test_core_vector__4(void) |
| { |
| git_vector x; |
| long i; |
| git_vector_init(&x, 1, &compare_them); |
| |
| for (i = 0; i < 10; i += 2) { |
| git_vector_insert_sorted(&x, (void*)(i + 1), NULL); |
| } |
| |
| for (i = 9; i > 0; i -= 2) { |
| git_vector_insert_sorted(&x, (void*)(i + 1), NULL); |
| } |
| |
| for (i = 0; i < 10; i += 2) { |
| git_vector_insert_sorted(&x, (void*)(i + 1), NULL); |
| } |
| |
| for (i = 9; i > 0; i -= 2) { |
| git_vector_insert_sorted(&x, (void*)(i + 1), NULL); |
| } |
| |
| cl_assert(x.length == 20); |
| for (i = 0; i < 20; ++i) { |
| cl_assert(git_vector_get(&x, i) == (void*)(i / 2 + 1)); |
| } |
| |
| git_vector_free(&x); |
| } |
| |
| typedef struct { |
| int content; |
| int count; |
| } my_struct; |
| |
| static int _struct_count = 0; |
| |
| static int compare_structs(const void *a, const void *b) |
| { |
| return ((const my_struct *)a)->content - |
| ((const my_struct *)b)->content; |
| } |
| |
| static int merge_structs(void **old_raw, void *new) |
| { |
| my_struct *old = *(my_struct **)old_raw; |
| cl_assert(((my_struct *)old)->content == ((my_struct *)new)->content); |
| ((my_struct *)old)->count += 1; |
| git__free(new); |
| _struct_count--; |
| return GIT_EEXISTS; |
| } |
| |
| static my_struct *alloc_struct(int value) |
| { |
| my_struct *st = git__malloc(sizeof(my_struct)); |
| st->content = value; |
| st->count = 0; |
| _struct_count++; |
| return st; |
| } |
| |
| /* insert_sorted with duplicates and special handling */ |
| void test_core_vector__5(void) |
| { |
| git_vector x; |
| int i; |
| |
| git_vector_init(&x, 1, &compare_structs); |
| |
| for (i = 0; i < 10; i += 2) |
| git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs); |
| |
| for (i = 9; i > 0; i -= 2) |
| git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs); |
| |
| cl_assert(x.length == 10); |
| cl_assert(_struct_count == 10); |
| |
| for (i = 0; i < 10; i += 2) |
| git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs); |
| |
| for (i = 9; i > 0; i -= 2) |
| git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs); |
| |
| cl_assert(x.length == 10); |
| cl_assert(_struct_count == 10); |
| |
| for (i = 0; i < 10; ++i) { |
| cl_assert(((my_struct *)git_vector_get(&x, i))->content == i); |
| git__free(git_vector_get(&x, i)); |
| _struct_count--; |
| } |
| |
| git_vector_free(&x); |
| } |
| |
| static int remove_ones(const git_vector *v, size_t idx) |
| { |
| return (git_vector_get(v, idx) == (void *)0x001); |
| } |
| |
| /* Test removal based on callback */ |
| void test_core_vector__remove_matching(void) |
| { |
| git_vector x; |
| size_t i; |
| void *compare; |
| |
| git_vector_init(&x, 1, NULL); |
| git_vector_insert(&x, (void*) 0x001); |
| |
| cl_assert(x.length == 1); |
| git_vector_remove_matching(&x, remove_ones); |
| cl_assert(x.length == 0); |
| |
| git_vector_insert(&x, (void*) 0x001); |
| git_vector_insert(&x, (void*) 0x001); |
| git_vector_insert(&x, (void*) 0x001); |
| |
| cl_assert(x.length == 3); |
| git_vector_remove_matching(&x, remove_ones); |
| cl_assert(x.length == 0); |
| |
| git_vector_insert(&x, (void*) 0x002); |
| git_vector_insert(&x, (void*) 0x001); |
| git_vector_insert(&x, (void*) 0x002); |
| git_vector_insert(&x, (void*) 0x001); |
| |
| cl_assert(x.length == 4); |
| git_vector_remove_matching(&x, remove_ones); |
| cl_assert(x.length == 2); |
| |
| git_vector_foreach(&x, i, compare) { |
| cl_assert(compare != (void *)0x001); |
| } |
| |
| git_vector_clear(&x); |
| |
| git_vector_insert(&x, (void*) 0x001); |
| git_vector_insert(&x, (void*) 0x002); |
| git_vector_insert(&x, (void*) 0x002); |
| git_vector_insert(&x, (void*) 0x001); |
| |
| cl_assert(x.length == 4); |
| git_vector_remove_matching(&x, remove_ones); |
| cl_assert(x.length == 2); |
| |
| git_vector_foreach(&x, i, compare) { |
| cl_assert(compare != (void *)0x001); |
| } |
| |
| git_vector_clear(&x); |
| |
| git_vector_insert(&x, (void*) 0x002); |
| git_vector_insert(&x, (void*) 0x001); |
| git_vector_insert(&x, (void*) 0x002); |
| git_vector_insert(&x, (void*) 0x001); |
| |
| cl_assert(x.length == 4); |
| git_vector_remove_matching(&x, remove_ones); |
| cl_assert(x.length == 2); |
| |
| git_vector_foreach(&x, i, compare) { |
| cl_assert(compare != (void *)0x001); |
| } |
| |
| git_vector_clear(&x); |
| |
| git_vector_insert(&x, (void*) 0x002); |
| git_vector_insert(&x, (void*) 0x003); |
| git_vector_insert(&x, (void*) 0x002); |
| git_vector_insert(&x, (void*) 0x003); |
| |
| cl_assert(x.length == 4); |
| git_vector_remove_matching(&x, remove_ones); |
| cl_assert(x.length == 4); |
| |
| git_vector_free(&x); |
| } |