added null-terminate option for strings

AuthorKonata <konata@posteo.jp>
Date
Commit1a0f31a42efbe5a812aea9003fa967ce8d9637f8
Parent8a4045d
3 files changed, 107 insertions(+), 79 deletions(-)
▾Minclude/cutils/dyn_string.h
@@ -12,10 +12,11 @@ typedef struct String
char* chars;
size_t capacity;
size_t length;
bool null_terminated;
} String;
#define new_string() string_with_capacity(STRING_DEFAULT_SIZE)
String* string_with_capacity(size_t capacity);
#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);
HEDLEY_INLINE
@@ -35,7 +36,7 @@ static void string_remove(String* string, size_t index)
{
if(index < string->length)
{
memmove(string->chars+index, string->chars+index+1, (string->length-index-1)*sizeof(*string->chars));
memmove(string->chars+index, string->chars+index+1, (string->length-index-1+(string->null_terminated?1:0))*sizeof(*string->chars));
string->length--;
}
}
@@ -59,9 +60,9 @@ size_t string_count(const String* string, char character);
bool string_concat(String* string, const String* other);
String* from_cstring(const char* cstring);
String* from_cstring_reuse(char* cstring, size_t capacity);
String* from_cstring_del(char* cstring);
String* from_cstring(const char* cstring, bool null_terminated);
String* from_cstring_reuse(char* cstring, size_t capacity, bool null_terminated);
String* from_cstring_del(char* cstring, bool null_terminated);
char* to_cstring(const String* string);
char* to_cstring_del(String* string);
void string_move(String* dest, String* src);
▾Msrc/dyn_string.c
@@ -1,25 +1,28 @@
#include <cutils/dyn_string.h>
String* string_with_capacity(size_t capacity)
String* string_with_capacity(size_t capacity, bool null_terminated)
{
String* string = malloc(sizeof(*string));
if(!string)
return NULL;
string->chars = calloc(capacity,sizeof(*string->chars));
string->chars = malloc(capacity+(null_terminated?1:0));
if(!string->chars)
{
free(string);
return NULL;
}
if(null_terminated)
string->chars[0] = '\0';
string->length = 0;
string->capacity = capacity;
string->null_terminated = null_terminated;
return string;
}
void string_remove_range(String* string, size_t index, size_t length)
{
memmove(string->chars+index, string->chars+index+length, (string->length-(index+length)));
memmove(string->chars+index, string->chars+index+length, (string->length-(index+length)+(string->null_terminated?1:0)));
string->length -= length;
}
@@ -44,7 +47,7 @@ size_t string_strip(String* string, char character)
}
}
memmove(string->chars+last-offset, string->chars+last+1, string->length-last-1);
memmove(string->chars+last-offset, string->chars+last+1, string->length-last-1+(string->null_terminated?1:0));
string->length -= offset+(first ? 0 : 1);
return offset;
@@ -52,10 +55,10 @@ size_t string_strip(String* string, char character)
bool string_insert(String* string, size_t index, char character)
{
if(index > string->length || string->length == SIZE_MAX || !string_adjust_size(string, string->length))
if(index > string->length || string->length == SIZE_MAX || !string_adjust_size(string, string->length+1))
return false;
memmove(string->chars+index+1, string->chars+index, (string->length-index)*sizeof(*string->chars));
memmove(string->chars+index+1, string->chars+index, (string->length-index+(string->null_terminated?1:0))*sizeof(*string->chars));
string->chars[index] = character;
string->length++;
return true;
@@ -64,13 +67,8 @@ bool string_insert(String* string, size_t index, char character)
char string_pop_at(String* string, size_t index)
{
char tmp = string_at(string, index);
if(!tmp)
{
return '\0';
} else {
string_remove(string, index);
return tmp;
}
string_remove(string, index);
return tmp;
}
bool string_concat(String* string, const String* other)
@@ -79,6 +77,7 @@ bool string_concat(String* string, const String* other)
return false;
memcpy(string->chars+string->length,other->chars,other->length);
string->length += other->length;
string->chars[string->length] = '\0';
return true;
}
@@ -110,7 +109,10 @@ size_t string_count(const String* string, char character)
bool string_adjust_size(String* string, size_t size)
{
while(string->capacity < size)
if(size == SIZE_MAX && string->null_terminated)
return false;
while(string->capacity < size+(string->null_terminated?1:0))
{
char* tmp = string->chars;
string->chars = cutil_reallocarray_inc(string->chars, sizeof(*string->chars), string->capacity, string->capacity);
@@ -131,20 +133,22 @@ void delete_string(String* string)
free(string);
}
String* from_cstring(const char* cstring)
String* from_cstring(const char* cstring, bool null_terminated)
{
String* string = string_with_capacity(strlen(cstring));
String* string = string_with_capacity(strlen(cstring), null_terminated);
if(!string)
{
return NULL;
} else {
memcpy(string->chars, cstring, strlen(cstring));
string->length = strlen(cstring);
if(null_terminated)
string->chars[string->length] = '\0';
return string;
}
}
String* from_cstring_reuse(char* cstring, size_t capacity)
String* from_cstring_reuse(char* cstring, size_t capacity, bool null_terminated)
{
String* string;
@@ -161,9 +165,11 @@ String* from_cstring_reuse(char* cstring, size_t capacity)
return string;
}
String* from_cstring_del(char* cstring)
String* from_cstring_del(char* cstring, bool null_terminated)
{
String* ret = from_cstring(cstring);
String* ret = from_cstring(cstring, null_terminated);
if(!ret)
return NULL;
free(cstring);
return ret;
}
▾Msrc/test.c
@@ -71,66 +71,87 @@ static void test_string(void)
String* string2;
char* cstring;
size_t tmp;
bool truth;
string = new_string();
for(truth = false; truth == false || truth == true; truth++)
{
string = new_string(truth);
string_push(string, 'a');
string_push(string, 'b');
string_push(string, 'c');
string_push(string, 'd');
assert(string->length == 4);
cstring = to_cstring(string);
assert(strcmp(cstring, "abcd") == 0);
free(cstring);
string_remove(string, 3);
cstring = to_cstring(string);
assert(strcmp(cstring, "abc") == 0);
free(cstring);
assert(string->length == 3);
string_insert(string, 0,'a');
cstring = to_cstring(string);
assert(strcmp(cstring, "aabc") == 0);
free(cstring);
string2 = from_cstring("xyz", truth);
string_concat(string,string2);
cstring = to_cstring(string);
assert(strcmp(cstring, "aabcxyz") == 0);
free(cstring);
delete_string(string2);
delete_string(string);
string = from_cstring("abcd", truth);
string2 = from_cstring("cd", truth);
assert(string_find_str(string, string2, &tmp));
assert(tmp == 2);
delete_string(string2);
delete_string(string);
string = from_cstring("abcd", truth);
assert(string->length == 4);
string_remove_range(string, 0, string->length);
assert(string->length == 0);
delete_string(string);
string = from_cstring("bba", truth);
string_strip(string, 'a');
assert(string->length == 2);
cstring = to_cstring_del(string);
free(cstring);
string = from_cstring("asdyx782", truth);
string2 = from_cstring("asdyx782", truth);
assert(string_cmp(string, string2) == 0);
delete_string(string2);
delete_string(string);
}
string = from_cstring("asdyx782", true);
string_push(string, 'a');
string_push(string, 'b');
string_push(string, 'c');
string_push(string, 'd');
assert(string->length == 4);
cstring = to_cstring(string);
assert(strcmp(cstring, "abcd") == 0);
free(cstring);
string_remove(string, 3);
cstring = to_cstring(string);
assert(strcmp(cstring, "abc") == 0);
free(cstring);
assert(string->length == 3);
string_insert(string, 0,'a');
cstring = to_cstring(string);
assert(strcmp(cstring, "aabc") == 0);
free(cstring);
string2 = from_cstring("xyz");
string_concat(string,string2);
cstring = to_cstring(string);
assert(strcmp(cstring, "aabcxyz") == 0);
free(cstring);
delete_string(string2);
delete_string(string);
string = from_cstring("abcd");
string2 = from_cstring("cd");
assert(string_find_str(string, string2, &tmp));
assert(tmp == 2);
string_remove(string, 2);
assert(strcmp(string->chars, "asyx782a") == 0);
string_remove_range(string, 1, 7);
assert(strcmp(string->chars, "a") == 0);
assert(string_pop(string) == 'a');
string2 = from_cstring("asdasdas", false);
string_concat(string, string2);
assert(strcmp(string->chars, "asdasdas") == 0);
delete_string(string2);
delete_string(string);
string = from_cstring("abcd");
assert(string->length == 4);
string_remove_range(string, 0, string->length);
assert(string->length == 0);
delete_string(string);
string2 = from_cstring("koasä_ #", true);
string_move(string, string2);
assert(strcmp(string->chars, "koasä_ #") == 0);
string = from_cstring("bba");
string_strip(string, 'a');
assert(string->length == 2);
cstring = to_cstring_del(string);
free(cstring);
string = from_cstring("asdyx782");
string2 = from_cstring("asdyx782");
assert(string_cmp(string, string2) == 0);
delete_string(string2);
delete_string(string);
}