changed naming form extension functions, added strnlen, str[n]dup and asprintf, added bitfuncs.h, changed find functions, added typedefs in misc.h
Minclude/cutils/backport.h
@@ -1,5 +1,5 @@
#ifndef BACKPORT_H
#define BACKPORT_H
#ifndef CUTILS_BACKPORT_H
#define CUTILS_BACKPORT_H
#include <limits.h>
#if __STDC_VERSION__ >= 199901L
@@ -116,4 +116,4 @@
#endif
#endif /* BACKPORT_H */
#endif /* CUTILS_BACKPORT_H */
Ainclude/cutils/bitfuncs.h
@@ -0,0 +1,17 @@
#ifndef CUTILS_BITFUNCS_H
#define CUTILS_BITFUNCS_H
#include <stdlib.h>
#include <cutils/common.h>
#define numbits(type) (sizeof(type)*CHAR_BIT)
#define bitstring(type, value) _bitstring(numbits(type), (type)(value))
/* FIXME: fix out of range calls (bitstring(unsigned char, 256)) */
char* _bitstring(size_t size, uintmax_t value);
#define getbit(type, value, bit) (((value) & (((type)1 << (bit)))) >> (bit))
#define setbit(type, value, bit) ((value) |= ((type)1 << (bit)))
#define clearbit(type, value, bit) ((value) &= (type)~((type)1 << (bit)))
#endif /* CUTILS_BITFUNCS_H */
Minclude/cutils/byte_array.h
@@ -1,5 +1,5 @@
#ifndef BYTE_ARRAY_H
#define BYTE_ARRAY_H
#ifndef CUTILS_BYTE_ARRAY_H
#define CUTILS_BYTE_ARRAY_H
#include <stdlib.h>
#include <string.h>
#include <errno.h>
@@ -9,7 +9,7 @@
typedef struct Bytearray
{
char* items;
byte* items;
size_t capacity;
size_t length;
size_t element_size;
@@ -34,5 +34,5 @@ HEDLEY_NON_NULL(3)
size_t* bytearray_find(const Bytearray* haystack, const void* needle, int (*cmp)(const void*, const void*));
#endif /* BYTE_ARRAY_H */
#endif /* CUTILS_BYTE_ARRAY_H */
Minclude/cutils/common.h
@@ -4,5 +4,6 @@
#include <cutils/backport.h>
#include <cutils/hedley.h>
#include <cutils/extensions.h>
#include <cutils/misc.h>
#endif /* CUTILS_COMMON_H */
Minclude/cutils/cutils.h
@@ -1,5 +1,5 @@
#ifndef CUTILS_H
#define CUTILS_H
#ifndef CUTILS_CUTILS_H
#define CUTILS_CUTILS_H
#include <cutils/vector.h>
#include <cutils/dyn_string.h>
@@ -8,5 +8,6 @@
#include <cutils/linked-list.h>
#include <cutils/extensions.h>
#include <cutils/backport.h>
#include <cutils/bitfuncs.h>
#endif /* CUTILS_H */
#endif /* CUTILS_CUTILS_H */
Minclude/cutils/dyn_string.h
@@ -1,5 +1,5 @@
#ifndef DYN_STRING_H
#define DYN_STRING_H
#ifndef CUTILS_DYN_STRING_H
#define CUTILS_DYN_STRING_H
#define STRING_DEFAULT_SIZE 8
@@ -31,8 +31,8 @@ void string_remove_range(String* string, size_t index, size_t length);
bool string_adjust_size(String* string, size_t size);
/* TODO: rework find functions to take extra argument of result count
* and then find that many and return them in a vector/linked list */
size_t* string_find_char(const String* haystack, const char needle);
size_t* string_find_str(const String* haystack, const String* needle);
bool string_find_char(const String* haystack, const char needle, size_t* pos);
bool string_find_str(const String* haystack, const String* needle, size_t* pos);
bool string_concat(String* string, const String* other);
@@ -42,4 +42,4 @@ char* to_cstring(const String* string);
char* to_cstring_del(String* string);
#endif /* DYN_STRING_H */
#endif /* CUTILS_DYN_STRING_H */
Minclude/cutils/extensions.h
@@ -1,5 +1,5 @@
#ifndef EXTENSIONS_H
#define EXTENSIONS_H
#ifndef CUTILS_EXTENSIONS_H
#define CUTILS_EXTENSIONS_H
#include <cutils/hedley.h>
#include <errno.h>
@@ -7,12 +7,23 @@
#include <cutils/backport.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
int strcmp_nocase(const char* s1, const char* s2);
int strncmp_nocase(const char* s1, const char* s2, size_t n);
int cutil_strcasecmp(const char* s1, const char* s2);
int cutil_strncasecmp(const char* s1, const char* s2, size_t n);
size_t cutil_strnlen(const char *s, size_t maxlen);
char* cutil_strdup(const char *s);
char* cutil_strndup(const char *s, size_t n);
#if __STDC_VERSION__ >= 199901L
int cutil_asprintf(char** strp, const char* format, ...);
#endif
HEDLEY_INLINE
static void* reallocsafe(void *ptr, size_t nmemb, size_t size)
static void* cutil_reallocarray(void *ptr, size_t nmemb, size_t size)
{
size_t new_size = nmemb * size;
@@ -26,17 +37,17 @@ static void* reallocsafe(void *ptr, size_t nmemb, size_t size)
}
HEDLEY_INLINE
static void* reallocsafe_inc(void *ptr, size_t nmemb, size_t size, size_t add)
static void* cutil_reallocarray_inc(void *ptr, size_t nmemb, size_t size, size_t add)
{
if(SIZE_MAX - add < size)
{
errno = ENOMEM;
return NULL;
} else {
return reallocsafe(ptr, nmemb, size+add);
return cutil_reallocarray(ptr, nmemb, size+add);
}
}
#endif /* EXTENSIONS_H */
#endif /* CUTILS_EXTENSIONS_H */
Minclude/cutils/linked-list.h
@@ -1,5 +1,5 @@
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
#ifndef CUTILS_LINKED_LIST_H
#define CUTILS_LINKED_LIST_H
#include <cutils/common.h>
#include <stdlib.h>
@@ -84,4 +84,4 @@ static void ll_swap(LinkedList* ll, size_t item1, size_t item2)
}
#endif /* LINKED_LIST_H */
#endif /* CUTILS_LINKED_LIST_H */
Minclude/cutils/misc.h
@@ -1,5 +1,5 @@
#ifndef MISC_H
#define MISC_H
#ifndef CUTILS_MISC_H
#define CUTILS_MISC_H
#ifdef __unix__
#ifndef _BSD_SOURCE
@@ -19,6 +19,16 @@
#include <cutils/common.h>
#include <ctype.h>
typedef unsigned char byte;
#ifndef CUTILS_NO_SHORTHANDLES
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ullong;
#endif /* CUTILS_NO_SHORTHANDLES */
#if __STDC_VERSION__ >= 199901L
#ifdef UINT32_MAX
uint32_t ntoh32(uint32_t const net);
@@ -26,7 +36,7 @@
HEDLEY_INLINE
static void memqswap_stack(void* item1, void* item2, size_t length)
{
unsigned char tmp[length];
byte tmp[length];
memcpy(tmp, item1, length);
memcpy(item1, item2, length);
memcpy(item2, tmp, length);
@@ -36,8 +46,8 @@
HEDLEY_INLINE
static void memswap(void* item1, void* item2, size_t length)
{
unsigned char *item1_tmp, *item2_tmp;
unsigned char tmp;
byte *item1_tmp, *item2_tmp;
byte tmp;
item1_tmp = item1;
item2_tmp = item2;
@@ -70,4 +80,4 @@ void sleep_ms(unsigned int milliseconds);
uintmax_t timespec_ms(const struct timespec* ts);
#endif
#endif /* MISC_H */
#endif /* CUTILS_MISC_H */
Minclude/cutils/vector.h
@@ -1,5 +1,5 @@
#ifndef VECTOR_H
#define VECTOR_H
#ifndef CUTILS_VECTOR_H
#define CUTILS_VECTOR_H
#define VECTOR_DEFAULT_SIZE 4
@@ -34,4 +34,4 @@ HEDLEY_NON_NULL(3)
size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const void*, const void*));
#endif /* VECTOR_H */
#endif /* CUTILS_VECTOR_H */
Asrc/bitfuncs.c
@@ -0,0 +1,22 @@
#include <cutils/bitfuncs.h>
char* _bitstring(size_t size, uintmax_t value)
{
char* ret = NULL;
size_t i, pos;
bool leading_zero = true;
for(i = 1, pos = 0; i <= size; i++)
{
byte tmp = (byte)((value & ((uintmax_t)1 << (size-i))) >> (size-i));
if(tmp && leading_zero)
{
leading_zero = false;
ret = malloc(size-i);
ret[size-i-1] = '\0';
}
if(!leading_zero)
ret[pos++] = tmp ? '1' : '0';
}
return ret;
}
Msrc/byte_array.c
@@ -95,8 +95,8 @@ bool bytearray_adjust_size(Bytearray* bytearray, size_t size)
{
while(bytearray->capacity < size)
{
char* tmp = bytearray->items;
bytearray->items = reallocsafe_inc(bytearray->items, sizeof(*bytearray->items), bytearray->capacity, bytearray->capacity);
byte* tmp = bytearray->items;
bytearray->items = cutil_reallocarray_inc(bytearray->items, bytearray->capacity, bytearray->element_size, bytearray->capacity);
if(!bytearray->items)
{
bytearray->items = tmp;
@@ -111,8 +111,8 @@ bool bytearray_shrink(Bytearray* bytearray)
{
while(bytearray->capacity > bytearray->length*2)
{
char* tmp = bytearray->items;
bytearray->items = realloc(bytearray->items, (bytearray->capacity*bytearray->element_size)/2);
byte* tmp = bytearray->items;
bytearray->items = cutil_reallocarray(bytearray->items, bytearray->capacity/2, bytearray->element_size);
if(!bytearray->items)
{
bytearray->items = tmp;
Msrc/dyn_string.c
@@ -75,41 +75,39 @@ bool string_concat(String* string, const String* other)
return true;
}
size_t* string_find_char(const String* haystack, const char needle)
bool string_find_char(const String* haystack, const char needle, size_t* pos)
{
size_t i, *ret;
size_t i;
for(i = 0; i < haystack->length; i++)
{
if(haystack->chars[i] == needle)
{
ret = malloc(sizeof(*ret));
*ret = i;
return ret;
*pos = i;
return true;
}
}
return NULL;
return false;
}
size_t* string_find_str(const String* haystack, const String* needle)
bool string_find_str(const String* haystack, const String* needle, size_t* pos)
{
size_t *ret, i, j, tmp;
size_t i, j, tmp;
for(i = 0; i < haystack->length; i++)
{
for(j = 0, tmp = i; j < needle->length; j++, i++)
for(j = 0, tmp = i; j < needle->length && i < haystack->length; j++, i++)
{
if(haystack->chars[i] != needle->chars[j])
{
break;
} else if(j == needle->length-1){
ret = malloc(sizeof(*ret));
*ret = tmp;
return ret;
*pos = tmp;
return true;
}
}
}
return NULL;
return false;
}
bool string_adjust_size(String* string, size_t size)
@@ -117,7 +115,7 @@ bool string_adjust_size(String* string, size_t size)
while(string->capacity < size)
{
char* tmp = string->chars;
string->chars = reallocsafe_inc(string->chars, sizeof(*string->chars), string->capacity, string->capacity);
string->chars = cutil_reallocarray_inc(string->chars, sizeof(*string->chars), string->capacity, string->capacity);
if(!string->chars)
{
string->chars = tmp;
Msrc/extensions.c
@@ -1,6 +1,6 @@
#include <cutils/extensions.h>
int strcmp_nocase(const char* s1, const char* s2)
int cutil_strcasecmp(const char* s1, const char* s2)
{
const unsigned char* p1 = (const unsigned char*)s1;
const unsigned char* p2 = (const unsigned char*)s2;
@@ -18,7 +18,7 @@ int strcmp_nocase(const char* s1, const char* s2)
return c1 - c2;
}
int strncmp_nocase(const char* s1, const char* s2, size_t n)
int cutil_strncasecmp(const char* s1, const char* s2, size_t n)
{
const unsigned char* p1 = (const unsigned char*)s1;
const unsigned char* p2 = (const unsigned char*)s2;
@@ -38,3 +38,60 @@ int strncmp_nocase(const char* s1, const char* s2, size_t n)
return c1 - c2;
}
size_t cutil_strnlen(const char *s, size_t maxlen)
{
size_t len;
for(len = 0; len < maxlen; len++, s++)
{
if (!*s)
break;
}
return (len);
}
char* cutil_strdup(const char *s)
{
char* ret;
size_t len = strlen(s);
ret = malloc(len+1);
memcpy(ret, s, len+1);
return ret;
}
char* cutil_strndup(const char *s, size_t n)
{
char* ret;
size_t len = cutil_strnlen(s, n);
len = len <= n ? len : n;
ret = malloc(len+1);
memcpy(ret, s, len+1);
return ret;
}
#if __STDC_VERSION__ >= 199901L
int cutil_asprintf(char** strp, const char* format, ...)
{
va_list ap;
size_t needed;
int ret;
va_start(ap, format);
needed = (size_t)vsnprintf(NULL, 0, format, ap);
va_end(ap);
*strp = malloc(needed);
va_start(ap, format);
ret = snprintf(*strp, needed, format, ap);
va_end(ap);
return ret;
}
#endif
Msrc/meson.build
@@ -1,4 +1,4 @@
src = ['vector.c', 'dyn_string.c', 'misc.c', 'byte_array.c', 'linked-list.c', 'extensions.c']
src = ['vector.c', 'dyn_string.c', 'misc.c', 'byte_array.c', 'linked-list.c', 'extensions.c', 'bitfuncs.c']
srctest = src + ['test.c']
cutils_lib = library('cutils', src, include_directories : inc, install: true)
Msrc/test.c
@@ -70,7 +70,7 @@ static void test_string(void)
String* string;
String* string2;
char* cstring;
size_t* tmp;
size_t tmp;
string = new_string();
@@ -107,9 +107,8 @@ static void test_string(void)
string = from_cstring("abcd");
string2 = from_cstring("cd");
tmp = string_find_str(string, string2);
assert(*tmp == 2);
free(tmp);
string_find_str(string, string2, &tmp);
assert(tmp == 2);
delete_string(string2);
delete_string(string);
@@ -127,7 +126,7 @@ static void test_bytearray(void)
bytearray_push(bt, "d");
bytearray_push(bt, "\0");
assert(strcmp(bt->items, "abcd") == 0);
assert(strcmp((char*)bt->items, "abcd") == 0);
tmpchar = bytearray_pop(bt, NULL);
assert(*tmpchar == '\0');
@@ -248,6 +247,24 @@ static void test_ll(void)
}
}
static void test_bitfuncs(void)
{
byte tmp = 0;
setbit(byte, tmp, 0);
assert(tmp == 1);
setbit(byte, tmp, 1);
assert(tmp == 3);
setbit(byte, tmp, 2);
assert(tmp == 7);
clearbit(byte, tmp, 2);
assert(tmp == 3);
assert(getbit(byte, tmp, 0) == 1);
assert(getbit(byte, tmp, 5) == 0);
}
int main(int argc, char** argv)
{
/* memswap tests */
@@ -276,13 +293,14 @@ int main(int argc, char** argv)
test_timespec();
#endif
test_ll();
test_bitfuncs();
/* misc tests */
sleep_ms(1000);
assert(strcmp_nocase("ASD", "aSd") == 0);
assert(strcmp_nocase("BSD", "asd") > 0);
assert(strcmp_nocase("ASD", "bsd") < 0);
assert(strncmp_nocase("ASDn", "asd", 3) == 0);
assert(strncmp_nocase("ASDn", "asd", 4) >0);
assert(cutil_strcasecmp("ASD", "aSd") == 0);
assert(cutil_strcasecmp("BSD", "asd") > 0);
assert(cutil_strcasecmp("ASD", "bsd") < 0);
assert(cutil_strncasecmp("ASDn", "asd", 3) == 0);
assert(cutil_strncasecmp("ASDn", "asd", 4) >0);
return 0;
}
Msrc/vector.c
@@ -90,7 +90,7 @@ bool vector_adjust_size(Vector* vector, size_t size)
while(vector->capacity < size)
{
void** tmp = vector->items;
vector->items = reallocsafe_inc(vector->items, sizeof(*vector->items), vector->capacity, vector->capacity);
vector->items = cutil_reallocarray_inc(vector->items, vector->capacity, sizeof(*vector->items), vector->capacity);
if(!vector->items)
{
vector->items = tmp;
@@ -106,7 +106,7 @@ 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 = cutil_reallocarray(vector->items, vector->capacity/2, sizeof(*vector->items));
if(!vector->items)
{
vector->items = tmp;