changed signature of delete_string() (for easier usage as rmv function)

added string_cmp_cstr()
added string_split() + tests
added casts to macros
changed name of ntoh32() to nethost32() (because it works both ways)
removed bounds check in insert functions
fixed bugs in string_concat() and from_cstring_reuse()
AuthorKonata <konata@posteo.jp>
Date
Commit1be90feadc584b8017b410735aaf8207e4e23ff4
Parent6fb96ec
9 files changed, 88 insertions(+), 18 deletions(-)
▾Minclude/cutils/byte_array.h
@@ -50,8 +50,8 @@ 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)
#define bytearray_pop(bytearray, retptr) bytearray_pop_at(bytearray, ((Vector*)vector)->length-1, retptr)
#define bytearray_push(bytearray, item) bytearray_insert(bytearray, ((Vector*)vector)->length, item)
#endif /* CUTILS_BYTE_ARRAY_H */
▾Minclude/cutils/dyn_string.h
@@ -6,6 +6,7 @@
#include <stdlib.h>
#include <string.h>
#include <cutils/common.h>
#include <cutils/vector.h>
typedef struct String
{
@@ -16,7 +17,7 @@ typedef struct String
} String;
String* string_with_capacity(size_t capacity, bool null_terminated);
void delete_string(String* string);
void delete_string(void* string);
HEDLEY_INLINE
static char string_at(const String* string, size_t index)
@@ -49,10 +50,10 @@ static bool string_find_str(const String* haystack, const String* needle, size_t
return cutil_memmem(haystack->chars, haystack->length, needle->chars, needle->length, pos);
}
int string_cmp(const String* s1, const String* s2);
int string_cmp_cstr(const String* s1, const char* s2);
size_t string_count(const String* string, char character);
bool string_concat(String* string, const String* other);
Vector* string_split(const String* string, const char* set, bool null_terminated);
String* from_cstring(const char* cstring, bool null_terminated);
String* from_cstring_reuse(char* cstring, size_t capacity, bool null_terminated);
@@ -62,7 +63,7 @@ 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)
#define string_pop(string) string_pop_at(string, ((String*)string)->length-1)
#define string_push(string, character) string_insert(string, ((String*)string)->length, character)
#endif /* CUTILS_DYN_STRING_H */
▾Minclude/cutils/misc.h
@@ -31,7 +31,7 @@ typedef unsigned long long ullong;
#if __STDC_VERSION__ >= 199901L
#ifdef UINT32_MAX
uint32_t ntoh32(uint32_t const net);
uint32_t nethost32(uint32_t const net);
#endif
HEDLEY_INLINE
static void memqswap_stack(void* item1, void* item2, size_t length)
▾Minclude/cutils/vector.h
@@ -46,7 +46,7 @@ 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)
#define vector_pop(vector) vector_pop_at(vector, ((Vector*)vector)->length-1)
#define vector_push(vector, item) vector_insert(vector, ((Vector*)vector)->length, item)
#endif /* CUTILS_VECTOR_H */
▾Msrc/byte_array.c
@@ -75,7 +75,7 @@ bool bytearray_insert(Bytearray* bytearray, size_t index, const void* item)
size_t length = bytearray->length;
size_t size = bytearray->element_size;
if(index > length || !bytearray_grow(bytearray, 1))
if(!bytearray_grow(bytearray, 1))
return false;
memmove(bytearray->items+index*size+1*size, bytearray->items+index*size, (length*size-index*size)*sizeof(*bytearray->items));
▾Msrc/dyn_string.c
@@ -55,7 +55,7 @@ size_t string_strip(String* string, char character)
bool string_insert(String* string, size_t index, char character)
{
if(index > string->length || !string_grow(string, 1))
if(!string_grow(string, 1))
return false;
memmove(string->chars+index+1, string->chars+index, (string->length-index+(string->null_terminated?1:0))*sizeof(*string->chars));
@@ -75,11 +75,12 @@ bool string_concat(String* string, const String* other)
{
if(other->length == 0)
return true;
if(!string_grow(string, other->length-1))
if(!string_grow(string, other->length))
return false;
memcpy(string->chars+string->length,other->chars,other->length);
string->length += other->length;
string->chars[string->length] = '\0';
if(string->null_terminated)
string->chars[string->length] = '\0';
return true;
}
@@ -104,6 +105,15 @@ int string_cmp(const String* s1, const String* s2)
return ret;
}
int string_cmp_cstr(const String* s1, const char* s2)
{
int ret = memcmp(s1->chars, s2, s1->length < strlen(s2) ? s1->length : strlen(s2));
if(ret == 0 && s1->length != strlen(s2))
return s1->length < strlen(s2) ? -1 : 1;
else
return ret;
}
size_t string_count(const String* string, char character)
{
@@ -116,6 +126,51 @@ size_t string_count(const String* string, char character)
return ret;
}
Vector* string_split(const String* string, const char* set, bool null_terminated)
{
#define CHECKRESULT(x) if(!x){delete_vector(ret, delete_string);return NULL;}
size_t i, currentvec = 0, currentlen = 0;
char c;
const char* orig = set;
String* tmp;
Vector* ret = new_vector();
bool is_delimiter = true;
if(!ret)
return NULL;
for(i = 0; i < string->length; i++)
{
for(c = *set++; c != '\0'; c = *set++)
{
if(string_at(string, i) == c)
{
is_delimiter = true;
currentlen = 0;
break;
} else {
is_delimiter = false;
}
}
if(!is_delimiter)
{
if(currentlen == 0)
{
tmp = new_string(null_terminated);
CHECKRESULT(tmp);
CHECKRESULT(vector_push(ret, tmp));
currentvec++;
}
currentlen++;
CHECKRESULT(string_push(vector_at(ret, currentvec-1), string_at(string, i)));
}
set = orig;
}
return ret;
#undef CHECKRESULT
}
bool string_grow(String* string, size_t add)
{
if(string->length+add < string->length)
@@ -143,9 +198,9 @@ bool string_adjust_size(String* string, size_t size)
}
void delete_string(String* string)
void delete_string(void* string)
{
free(string->chars);
free(((String*)string)->chars);
free(string);
}
@@ -178,6 +233,7 @@ String* from_cstring_reuse(char* cstring, size_t capacity, bool null_terminated)
string->chars = cstring;
string->length = strlen(cstring);
string->capacity = capacity;
string->null_terminated = null_terminated;
return string;
}
▾Msrc/misc.c
@@ -12,7 +12,7 @@ void sleep_ms(unsigned int milliseconds)
#if __STDC_VERSION__ >= 199901L
#ifdef UINT32_MAX
uint32_t ntoh32(uint32_t const net)
uint32_t nethost32(uint32_t const net)
{
uint8_t data[4];
memcpy(&data, &net, sizeof(data));
▾Msrc/test.c
@@ -72,6 +72,7 @@ static void test_string(void)
char* cstring;
size_t tmp;
int truth;
Vector* vec;
for(truth = false; truth == false || truth == true; truth++)
{
@@ -160,6 +161,18 @@ static void test_string(void)
free(string);
free(string2);
string = from_cstring(" -hi1 hi2 hello3 ; hi4!-!hi5- ", false);
vec = string_split(string, " ;-", true);
assert(vec->length == 5);
assert(string_cmp_cstr(vector_at(vec,0), "hi1") == 0);
assert(string_cmp_cstr(vector_at(vec,1), "hi2") == 0);
assert(string_cmp_cstr(vector_at(vec,2), "hello3") == 0);
assert(string_cmp_cstr(vector_at(vec,3), "hi4!") == 0);
assert(string_cmp_cstr(vector_at(vec,4), "!hi5") == 0);
delete_string(string);
delete_vector(vec, delete_string);
}
static void test_bytearray(void)
▾Msrc/vector.c
@@ -61,7 +61,7 @@ size_t* vector_find(const Vector* haystack, const void* needle, int (*cmp)(const
bool vector_insert(Vector* vector, size_t index, void* item)
{
if(index > vector->length || !vector_grow(vector, 1))
if(!vector_grow(vector, 1))
return false;
memmove(vector->items+index+1, vector->items+index, (vector->length-index)*sizeof(*vector->items));