added tests, simplified some functions, added functions
MMakefile
@@ -1,3 +1,9 @@
all:
gcc -Og -g -march=native -shared -fPIC -fstrict-aliasing vector.c dyn_string.c -o cutils.so -flto \
-Wall -Wpedantic -Wnull-dereference -Wshadow -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wstrict-overflow=5 -Wunreachable-code -Wno-unused-parameter
gcc -Og -g -march=native -shared -fPIC -fstrict-aliasing vector.c dyn_string.c -o libcutils.so -flto \
-Wall -Wpedantic -Wnull-dereference -Wshadow -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wstrict-overflow=5 -Wunreachable-code -Wno-unused-parameter \
-fsanitize=undefined
test:
gcc -Og -g -march=native -fPIC -fstrict-aliasing vector.c dyn_string.c test.c -o test -flto \
-Wall -Wpedantic -Wnull-dereference -Wshadow -Wconversion -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wstrict-overflow=5 -Wunreachable-code -Wno-unused-parameter \
-fsanitize=undefined
Mdyn_string.c
@@ -1,28 +1,30 @@
#include "dyn_string.h"
String* new_string(void)
{
return string_with_capacity(STRING_DEFAULT_SIZE);
}
String* string_with_capacity(size_t capacity)
{
String* string = malloc(sizeof(*string));
if(!string)
return NULL;
string->chars = calloc(sizeof(*string->chars)*STRING_DEFAULT_SIZE,1);
string->chars = calloc(capacity,sizeof(*string->chars));
if(!string->chars)
{
free(string);
return NULL;
}
string->length = 0;
string->capacity = STRING_DEFAULT_SIZE;
string->capacity = capacity;
return string;
}
bool string_append(String* string, char character)
{
if(!string_adjust_size(string, ++string->length))
return false;
string->chars[string->length-1] = character;
return true;
return string_insert(string, string->length, character);
}
void string_remove(String* string, size_t index)
@@ -36,7 +38,7 @@ void string_remove(String* string, size_t index)
bool string_insert(String* string, size_t index, char character)
{
if(!string_adjust_size(string, string->length))
if(index > string->length || !string_adjust_size(string, string->length))
return false;
memmove(string->chars+index+1, string->chars+index, (string->length-index)*sizeof(*string->chars));
@@ -53,11 +55,12 @@ char string_at(const String* string, size_t index)
return string->chars[index];
}
bool string_concat(String* string, String* other)
bool string_concat(String* string, const String* other)
{
if(!string_adjust_size(string,string->length+other->length-1))
return false;
memcpy(string->chars+string->length,other->chars,other->length);
string->length += other->length;
return true;
}
@@ -89,16 +92,36 @@ bool string_adjust_size(String* string, size_t size)
}
string->capacity *= 2;
}
while(string->capacity > (size*2))
return true;
}
void delete_string(String* string)
{
free(string->chars);
free(string);
}
String* from_cstring(const char* cstring)
{
String* string = string_with_capacity(strlen(cstring));
if(!string)
{
char* tmp = string->chars;
string->chars = realloc(string->chars, string->capacity/2*(sizeof(*string->chars)));
if(!string->chars)
{
string->chars = tmp;
return false;
}
string->capacity /= 2;
return NULL;
} else {
memcpy(string->chars, cstring, strlen(cstring));
string->length = strlen(cstring);
return string;
}
return true;
}
char* to_cstring(const String* string)
{
char* cstring = malloc(string->length+1);
memcpy(cstring, string->chars, string->length);
cstring[string->length] = '\0';
return cstring;
}
Mdyn_string.h
@@ -14,13 +14,22 @@ typedef struct String
} String;
String* new_string(void);
String* string_with_capacity(size_t capacity);
void delete_string(String* string);
char string_at(const String* string, size_t index);
bool string_append(String* string, char item);
bool string_append(String* string, char character);
bool string_insert(String* string, size_t index, char character);
void string_remove(String* string, size_t index);
bool string_adjust_size(String* string, size_t size);
size_t* string_find_char(const String* haystack, const char needle);
bool string_insert(String* string, size_t index, char character);
bool string_concat(String* string, String* other);
bool string_concat(String* string, const String* other);
String* from_cstring(const char* cstring);
char* to_cstring(const String* string);
#endif //DYN_STRING_H
Atest.c
@@ -0,0 +1,101 @@
#include "cutils.h"
#include <stdio.h>
struct test
{
int a;
int b;
};
int cmp_str(const void* str1, const void* str2)
{
const struct test* str1_s = str1;
const struct test* str2_s = str2;
return !((str1_s->a == str2_s->a) && (str1_s->b == str2_s->b));
}
void test1(void)
{
Vector* test = new_vector();
struct test* my_struct = malloc(sizeof(*my_struct));
my_struct->a = 5;
my_struct->b = 5;
vector_push(test, my_struct);
my_struct = malloc(sizeof(*my_struct));
my_struct->a = 6;
my_struct->b = 6;
vector_push(test, my_struct);
my_struct = malloc(sizeof(*my_struct));
my_struct->a = 7;
my_struct->b = 7;
vector_push(test, my_struct);
printf("%ld\n", test->length);
vector_remove(test, 0,free);
printf("%ld\n", test->length);
my_struct = malloc(sizeof(*my_struct));
my_struct->a = 8;
my_struct->b = 8;
vector_insert(test, 2, my_struct);
printf("%ld\n", test->length);
my_struct = malloc(sizeof(*my_struct));
my_struct->a = 8;
my_struct->b = 8;
size_t* find = vector_find(test, my_struct, cmp_str);
printf("pos: %lu\n", *find);
free(find);
free(my_struct);
my_struct = vector_pop(test);
printf("struct a: %d, b: %d\n", my_struct->a, my_struct->b);
free(my_struct);
delete_vector(test,free);
}
void test2(void)
{
String* test = new_string();
string_append(test, 'a');
string_append(test, 'b');
string_append(test, 'c');
string_append(test, 'd');
printf("%ld\n", test->length);
char* cstring = to_cstring(test);
printf("%s\n", cstring);
free(cstring);
string_remove(test, 3);
cstring = to_cstring(test);
printf("%s\n", cstring);
free(cstring);
printf("%ld\n", test->length);
string_insert(test, 0,'a');
cstring = to_cstring(test);
printf("%s\n", cstring);
free(cstring);
String* test2 = from_cstring("xyz");
string_concat(test,test2);
cstring = to_cstring(test);
printf("%s\n", cstring);
free(cstring);
delete_string(test2);
delete_string(test);
}
int main(int argc, char** argv)
{
test1();
test2();
}
Mvector.c
@@ -1,18 +1,23 @@
#include "vector.h"
Vector* new_vector(void)
{
return vector_with_capacity(VECTOR_DEFAULT_SIZE);
}
Vector* vector_with_capacity(size_t capacity)
{
Vector* vector = malloc(sizeof(*vector));
if(!vector)
return NULL;
vector->items = malloc(sizeof(*vector->items)*VECTOR_DEFAULT_SIZE);
vector->items = malloc(sizeof(*vector->items)*capacity);
if(!vector->items)
{
free(vector);
return NULL;
}
vector->length = 0;
vector->capacity = VECTOR_DEFAULT_SIZE;
vector->capacity = capacity;
return vector;
}
@@ -25,27 +30,30 @@ void* vector_at(const Vector* vector, size_t index)
return vector->items[index];
}
void* vector_pop(Vector* vector, size_t index)
void* vector_pop(Vector* vector)
{
if(index >= vector->length)
return NULL;
else
return vector_pop_at(vector, vector->length-1);
}
void* vector_pop_at(Vector* vector, size_t index)
{
void* tmp = vector_at(vector, index);
if(!tmp)
{
void* tmp = vector->items[index];
memmove(vector->items+index, vector->items+index+1, (vector->length-index-1)*sizeof(*vector->items));
vector->length--;
return NULL;
} else {
vector_remove(vector, index, NULL);
return tmp;
}
}
void vector_remove(Vector* vector, size_t index, void (*rmv)(void*))
{
if(index < vector->length)
{
if(rmv)
rmv(vector->items[index]);
else
free(vector->items[index]);
memmove(vector->items+index, vector->items+index+1, (vector->length-index-1)*sizeof(*vector->items));
vector->length--;
}
@@ -53,18 +61,15 @@ void vector_remove(Vector* vector, size_t index, void (*rmv)(void*))
bool vector_push(Vector* vector, void* item)
{
if(!vector_adjust_size(vector, ++vector->length))
return false;
vector->items[vector->length-1] = item;
return true;
return vector_insert(vector, vector->length, item);
}
size_t* vector_find(const Vector* haystack, const void* needle, bool (*cmp)(const void*, const void*))
size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const void*, const void*))
{
size_t* ret;
for(size_t i = 0; i < haystack->length; i++)
{
if(cmp ? cmp(haystack->items[i],needle) : haystack->items[i] == needle)
if(cmp ? cmp(haystack->items[i],needle) == 0 : haystack->items[i] == needle)
{
ret = malloc(sizeof(*ret));
*ret = i;
@@ -76,12 +81,12 @@ size_t* vector_find(const Vector* haystack, const void* needle, bool (*cmp)(cons
bool vector_insert(Vector* vector, size_t index, void* item)
{
if(!vector_adjust_size(vector, vector->length))
if(index > vector->length || !vector_adjust_size(vector, vector->length+1))
return false;
memmove(vector->items+index+1, vector->items+index, (vector->length-index)*sizeof(*vector->items));
vector->items[index] = item;
vector->length++;
++vector->length;
return true;
}
@@ -90,7 +95,7 @@ bool vector_adjust_size(Vector* vector, size_t size)
while(vector->capacity < size)
{
void** tmp = vector->items;
vector->items = realloc(vector->items, vector->capacity*2*(sizeof(*vector->items)));
vector->items = realloc(vector->items, vector->capacity*2*sizeof(*vector->items));
if(!vector->items)
{
vector->items = tmp;
@@ -98,10 +103,15 @@ bool vector_adjust_size(Vector* vector, size_t size)
}
vector->capacity *= 2;
}
while(vector->capacity > (size*2))
return true;
}
bool vector_shrink(Vector* vector)
{
while(vector->capacity > (vector->length*2))
{
void** tmp = vector->items;
vector->items = realloc(vector->items, vector->capacity/2*(sizeof(*vector->items)));
vector->items = realloc(vector->items, vector->capacity/2*sizeof(*vector->items));
if(!vector->items)
{
vector->items = tmp;
@@ -118,8 +128,7 @@ void delete_vector(Vector* vector, void (*rmv)(void*))
{
if(rmv)
rmv(vector->items[i]);
else
free(vector->items[i]);
}
free(vector->items);
free(vector);
}
Mvector.h
@@ -14,14 +14,21 @@ typedef struct Vector
} Vector;
Vector* new_vector(void);
Vector* vector_with_capacity(size_t capacity);
void delete_vector(Vector* vector, void(*rmv) (void*));
void* vector_at(const Vector* vector, size_t index);
void* vector_pop(Vector* vector, size_t index);
void* vector_pop(Vector* vector);
void* vector_pop_at(Vector* vector, size_t index);
bool vector_insert(Vector* vector, size_t index, void* item);
bool vector_push(Vector* vector, void* item);
void vector_remove(Vector* vector, size_t index, void (*rmv)(void*));
void delete_vector(Vector* vector, void(*rmv) (void*));
bool vector_adjust_size(Vector* vector, size_t size);
size_t* vector_find(const Vector* haystack, const void* needle, bool (*cmp)(const void*, const void*));
bool vector_insert(Vector* vector, size_t index, void* item);
bool vector_shrink(Vector* vector);
size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const void*, const void*));
#endif //VECTOR_H