mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-02 16:20:01 +00:00

This fixes some missed places where we can apply const-ness to various public APIs. There are still some index and tree APIs that cannot take const pointers because we sort our `git_vectors` lazily and so we can't reliably bsearch the index and tree content without applying a `git_vector_sort()` first. This also fixes some missed places where size_t can be used and where const can be applied to a couple internal functions.
276 lines
5.9 KiB
C
276 lines
5.9 KiB
C
#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);
|
|
}
|