moved the convenience macros of vector/bytearray/string to bottom, added math.h/.c with isqrt(), ipow(), is_prime(), primesieve(), added tests, fixed bug in reallocarray_inc() and string_cmp, use memchr for string_find_char(),

AuthorKonata <konata@posteo.jp>
Date
Commit8220e00ef6237c8deab917ad7eb9933a01a54932
Parent1245ac7
11 files changed, 173 insertions(+), 31 deletions(-)
▾Minclude/cutils/byte_array.h
@@ -15,7 +15,6 @@ typedef struct Bytearray
size_t element_size;
} Bytearray;
#define new_bytearray(element_size) bytearray_with_capacity(BYTEARRAY_DEFAULT_SIZE, element_size)
Bytearray* bytearray_with_capacity(size_t capacity, size_t element_size);
void delete_bytearray(Bytearray* bytearray, void(*rmv_el) (void*));
@@ -24,10 +23,8 @@ static void* bytearray_at(const Bytearray* bytearray, size_t index)
{
return bytearray->items+(index*bytearray->element_size);
}
#define bytearray_pop(bytearray, retptr) bytearray_pop_at(bytearray, bytearray->length-1, retptr)
void* bytearray_pop_at(Bytearray* bytearray, size_t index, void* retptr);
#define bytearray_push(bytearray, item) bytearray_insert(bytearray, bytearray->length, item)
bool bytearray_insert(Bytearray* bytearray, size_t index, const void* item);
HEDLEY_INLINE
@@ -52,6 +49,9 @@ bool bytearray_shrink(Bytearray* bytearray);
HEDLEY_NON_NULL(3)
size_t* bytearray_find(const Bytearray* haystack, const void* needle, int (*cmp)(const void*, const void*));
#define new_bytearray(element_size) bytearray_with_capacity(BYTEARRAY_DEFAULT_SIZE, element_size)
#define bytearray_pop(bytearray, retptr) bytearray_pop_at(bytearray, bytearray->length-1, retptr)
#define bytearray_push(bytearray, item) bytearray_insert(bytearray, bytearray->length, item)
#endif /* CUTILS_BYTE_ARRAY_H */
▾Minclude/cutils/cutils.h
@@ -9,5 +9,6 @@
#include <cutils/extensions.h>
#include <cutils/backport.h>
#include <cutils/bitfuncs.h>
#include <cutils/math.h>
#endif /* CUTILS_CUTILS_H */
▾Minclude/cutils/dyn_string.h
@@ -15,7 +15,6 @@ typedef struct String
bool null_terminated;
} String;
#define new_string(null_terminated) string_with_capacity(STRING_DEFAULT_SIZE, null_terminated)
String* string_with_capacity(size_t capacity, bool null_terminated);
void delete_string(String* string);
@@ -25,11 +24,9 @@ static char string_at(const String* string, size_t index)
return string->chars[index];
}
#define string_pop(string) string_pop_at(string, string->length-1)
char string_pop_at(String* string, size_t index);
bool string_insert(String* string, size_t index, char character);
#define string_push(string, character) string_insert(string, string->length, character)
HEDLEY_INLINE
static void string_remove(String* string, size_t index)
@@ -45,17 +42,13 @@ size_t string_strip(String* string, char character);
bool string_grow(String* string, size_t add);
bool string_adjust_size(String* string, size_t size);
bool string_find_char(const String* haystack, const char needle, size_t* pos);
bool string_find_char(const String* haystack, char needle, size_t* pos);
HEDLEY_INLINE
static bool string_find_str(const String* haystack, const String* needle, size_t* pos)
{
return cutil_memmem(haystack->chars, haystack->length, needle->chars, needle->length, pos);
}
HEDLEY_INLINE
static int string_cmp(const String* s1, const String* s2)
{
return memcmp(s1->chars, s2->chars, s1->length);
}
int string_cmp(const String* s1, const String* s2);
size_t string_count(const String* string, char character);
@@ -68,4 +61,8 @@ char* to_cstring(const String* string);
char* to_cstring_del(String* string);
void string_move(String* dest, String* src);
#define new_string(null_terminated) string_with_capacity(STRING_DEFAULT_SIZE, null_terminated)
#define string_pop(string) string_pop_at(string, string->length-1)
#define string_push(string, character) string_insert(string, string->length, character)
#endif /* CUTILS_DYN_STRING_H */
▾Minclude/cutils/extensions.h
@@ -47,7 +47,7 @@ static void* cutil_reallocarray_inc(void *ptr, size_t nmemb, size_t size, size_t
errno = ENOMEM;
return NULL;
} else {
return cutil_reallocarray(ptr, nmemb, size+add);
return cutil_reallocarray(ptr, nmemb+add, size);
}
}
▾Ainclude/cutils/math.h
@@ -0,0 +1,16 @@
#ifndef CUTILS_MATH_H
#define CUTILS_MATH_H
#include <cutils/common.h>
#include <cutils/byte_array.h>
#include <cutils/bitfuncs.h>
uintmax_t isqrt(uintmax_t n);
intmax_t ipow(intmax_t base, uintmax_t exp);
bool is_prime(uintmax_t n);
Bytearray* primesieve(uintmax_t limit);
#endif /* CUTILS_MATH_H */
▾Minclude/cutils/vector.h
@@ -14,7 +14,6 @@ typedef struct Vector
size_t length;
} Vector;
#define new_vector() vector_with_capacity(VECTOR_DEFAULT_SIZE)
Vector* vector_with_capacity(size_t capacity);
void delete_vector(Vector* vector, void(*rmv) (void*));
@@ -23,11 +22,9 @@ static void* vector_at(const Vector* vector, size_t index)
{
return vector->items[index];
}
#define vector_pop(vector) vector_pop_at(vector, vector->length-1)
void* vector_pop_at(Vector* vector, size_t index);
bool vector_insert(Vector* vector, size_t index, void* item);
#define vector_push(vector, item) vector_insert(vector, vector->length, item)
HEDLEY_INLINE
static void vector_remove(Vector* vector, size_t index, void (*rmv)(void*))
@@ -48,5 +45,8 @@ bool vector_shrink(Vector* vector);
HEDLEY_NON_NULL(3)
size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const void*, const void*));
#define new_vector() vector_with_capacity(VECTOR_DEFAULT_SIZE)
#define vector_pop(vector) vector_pop_at(vector, vector->length-1)
#define vector_push(vector, item) vector_insert(vector, vector->length, item)
#endif /* CUTILS_VECTOR_H */
▾Mmeson.build
@@ -1,7 +1,7 @@
project('cutils', 'c')
WARNINGS = ['-Wall', '-Wpedantic', '-Wextra', '-Wnull-dereference', '-Wshadow', '-Wconversion', '-Wstrict-prototypes', '-Wmissing-prototypes', '-Wcast-qual', '-Wstrict-overflow=5', '-Wunreachable-code', '-Wno-unused-parameter', '-Wno-unused-function']
CFLAGS = ['-std=c89', '-fstrict-aliasing', '-fPIC', '-Wno-long-long'] + WARNINGS
WARNINGS = ['-Wall', '-Wpedantic', '-Wextra', '-Wnull-dereference', '-Wshadow', '-Wconversion', '-Wstrict-prototypes', '-Wmissing-prototypes', '-Wcast-qual', '-Wstrict-overflow=5', '-Wunreachable-code', '-Wno-unused-parameter', '-Wno-unused-function', '-Wno-long-long']
CFLAGS = ['-std=c89', '-fstrict-aliasing', '-fPIC', '-Wno-long-long', '-Og'] + WARNINGS
subdir('include')
subdir('src')
▾Msrc/dyn_string.c
@@ -83,21 +83,28 @@ bool string_concat(String* string, const String* other)
return true;
}
bool string_find_char(const String* haystack, const char needle, size_t* pos)
bool string_find_char(const String* haystack, char needle, size_t* pos)
{
size_t i;
for(i = 0; i < haystack->length; i++)
char* ret = memchr(haystack->chars, needle, haystack->length);
if(!ret)
{
if(haystack->chars[i] == needle)
{
*pos = i;
return true;
}
return false;
} else {
*pos = (size_t)(ret-haystack->chars);
return true;
}
return false;
}
int string_cmp(const String* s1, const String* s2)
{
int ret = memcmp(s1->chars, s2->chars, s1->length < s2->length ? s1->length : s2->length);
if(ret == 0 && s1->length != s2->length)
return s1->length < s2->length ? -1 : 1;
else
return ret;
}
size_t string_count(const String* string, char character)
{
size_t i, ret = 0;
@@ -161,13 +168,14 @@ String* from_cstring_reuse(char* cstring, size_t capacity, bool null_terminated)
{
String* string;
if(cstring)
if(!cstring)
return NULL;
string = malloc(sizeof(*string));
if(!string)
return NULL;
string->chars = cstring;
string->length = strlen(cstring);
string->capacity = capacity;
▾Asrc/math.c
@@ -0,0 +1,103 @@
#include <cutils/math.h>
uintmax_t isqrt(uintmax_t n)
{
uintmax_t start = 1, end = n/2, ans;
if(n == 0 || n == 1)
return n;
while(start <= end)
{
uintmax_t mid = (start + end) / 2;
if(mid*mid == n)
return mid;
if(mid*mid < n)
{
start = mid + 1;
ans = mid;
} else {
end = mid - 1;
}
}
return ans;
}
intmax_t ipow(intmax_t base, uintmax_t exp)
{
intmax_t result = 1;
while (exp)
{
if (exp & 1)
result *= base;
exp >>= 1;
base *= base;
}
return result;
}
bool is_prime(uintmax_t n)
{
uintmax_t i;
if (n < 2) return false;
if (n % 2 == 0 && n != 2) return false;
for(i = 3; i < isqrt(n); i+=2)
{
if (n % i == 0)
return false;
}
return true;
}
static void primesieve_set(byte* numbers, size_t index)
{
numbers[index/8] |= (byte)(1 << (index%8));
}
static bool primesieve_get(byte* numbers, size_t index)
{
return getbit(byte, (numbers[index/8] >> index%8), 0);
}
#include <assert.h>
Bytearray* primesieve(uintmax_t limit)
{
size_t i, j, length = limit/8+1;
byte* numbers;
Bytearray* bt;
numbers = calloc(length, 1);
if(!numbers)
return NULL;
bt = new_bytearray(sizeof(uintmax_t));
if(!numbers)
{
free(numbers);
return NULL;
}
for(i = 2; i < isqrt(limit); i++)
{
if(primesieve_get(numbers, i) == 0)
{
for(j = i*i; j < limit; j+=i)
{
primesieve_set(numbers, j);
}
}
}
for(i = 0; i < limit; i++)
{
if(primesieve_get(numbers, i) == 0)
bytearray_push(bt, &i);
}
free(numbers);
return bt;
}
▾Msrc/meson.build
@@ -1,4 +1,4 @@
src = ['vector.c', 'dyn_string.c', 'misc.c', 'byte_array.c', 'linked-list.c', 'extensions.c', 'bitfuncs.c']
src = ['vector.c', 'dyn_string.c', 'misc.c', 'byte_array.c', 'linked-list.c', 'extensions.c', 'bitfuncs.c', 'math.c']
srctest = src + ['test.c']
cutils_lib = library('cutils', src, include_directories : inc, install: true)
▾Msrc/test.c
@@ -153,6 +153,13 @@ static void test_string(void)
assert(strcmp(string->chars, "koasä_ #") == 0);
delete_string(string);
string = from_cstring_reuse("asdasdas1", strlen("asdasdas1"), false);
string2 = from_cstring_reuse("asdasdas", strlen("asdasdas"), false);
assert(string_cmp(string, string2) > 0);
free(string);
free(string2);
}
static void test_bytearray(void)
@@ -258,7 +265,7 @@ static void test_ll(void)
{
LinkedList* ll;
struct test my_structa, my_structb, *my_structptr;
int truth;
bool truth;
my_structa.a = 5;
my_structa.b = 5;
my_structb.a = 7;
@@ -316,6 +323,7 @@ int main(int argc, char** argv)
/* memswap tests */
int a = 5;
int b = 2;
Bytearray* bt;
void* tmp = malloc(sizeof(int));
memswap(&a, &b, sizeof(int));
@@ -348,5 +356,14 @@ int main(int argc, char** argv)
assert(cutil_strcasecmp("ASD", "bsd") < 0);
assert(cutil_strncasecmp("ASDn", "asd", 3) == 0);
assert(cutil_strncasecmp("ASDn", "asd", 4) >0);
assert(ipow(2,32) == 4294967296);
assert(isqrt(123123) == 350);
bt = primesieve(100000000);
assert(*(uintmax_t*)bytearray_at(bt, 312312) == 4444697);
delete_bytearray(bt, NULL);
return 0;
}