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
1212 char* chars;
1313 size_t capacity;
1414 size_t length;
15+ bool null_terminated;
1516 } String;
1617
17-#define new_string() string_with_capacity(STRING_DEFAULT_SIZE)
18-String* string_with_capacity(size_t capacity);
18+#define new_string(null_terminated) string_with_capacity(STRING_DEFAULT_SIZE, null_terminated)
19+String* string_with_capacity(size_t capacity, bool null_terminated);
1920 void delete_string(String* string);
2021
2122 HEDLEY_INLINE
@@ -35,7 +36,7 @@ static void string_remove(String* string, size_t index)
3536 {
3637 if(index < string->length)
3738 {
38- memmove(string->chars+index, string->chars+index+1, (string->length-index-1)*sizeof(*string->chars));
39+ memmove(string->chars+index, string->chars+index+1, (string->length-index-1+(string->null_terminated?1:0))*sizeof(*string->chars));
3940 string->length--;
4041 }
4142 }
@@ -59,9 +60,9 @@ size_t string_count(const String* string, char character);
5960
6061 bool string_concat(String* string, const String* other);
6162
62-String* from_cstring(const char* cstring);
63-String* from_cstring_reuse(char* cstring, size_t capacity);
64-String* from_cstring_del(char* cstring);
63+String* from_cstring(const char* cstring, bool null_terminated);
64+String* from_cstring_reuse(char* cstring, size_t capacity, bool null_terminated);
65+String* from_cstring_del(char* cstring, bool null_terminated);
6566 char* to_cstring(const String* string);
6667 char* to_cstring_del(String* string);
6768 void string_move(String* dest, String* src);
Msrc/dyn_string.c
@@ -1,25 +1,28 @@
11 #include <cutils/dyn_string.h>
22
3-String* string_with_capacity(size_t capacity)
3+String* string_with_capacity(size_t capacity, bool null_terminated)
44 {
55 String* string = malloc(sizeof(*string));
66 if(!string)
77 return NULL;
8- string->chars = calloc(capacity,sizeof(*string->chars));
8+ string->chars = malloc(capacity+(null_terminated?1:0));
99 if(!string->chars)
1010 {
1111 free(string);
1212 return NULL;
1313 }
14+ if(null_terminated)
15+ string->chars[0] = '\0';
1416 string->length = 0;
1517 string->capacity = capacity;
18+ string->null_terminated = null_terminated;
1619
1720 return string;
1821 }
1922
2023 void string_remove_range(String* string, size_t index, size_t length)
2124 {
22- memmove(string->chars+index, string->chars+index+length, (string->length-(index+length)));
25+ memmove(string->chars+index, string->chars+index+length, (string->length-(index+length)+(string->null_terminated?1:0)));
2326 string->length -= length;
2427 }
2528
@@ -44,7 +47,7 @@ size_t string_strip(String* string, char character)
4447 }
4548 }
4649
47- memmove(string->chars+last-offset, string->chars+last+1, string->length-last-1);
50+ memmove(string->chars+last-offset, string->chars+last+1, string->length-last-1+(string->null_terminated?1:0));
4851
4952 string->length -= offset+(first ? 0 : 1);
5053 return offset;
@@ -52,10 +55,10 @@ size_t string_strip(String* string, char character)
5255
5356 bool string_insert(String* string, size_t index, char character)
5457 {
55- if(index > string->length || string->length == SIZE_MAX || !string_adjust_size(string, string->length))
58+ if(index > string->length || string->length == SIZE_MAX || !string_adjust_size(string, string->length+1))
5659 return false;
5760
58- memmove(string->chars+index+1, string->chars+index, (string->length-index)*sizeof(*string->chars));
61+ memmove(string->chars+index+1, string->chars+index, (string->length-index+(string->null_terminated?1:0))*sizeof(*string->chars));
5962 string->chars[index] = character;
6063 string->length++;
6164 return true;
@@ -64,13 +67,8 @@ bool string_insert(String* string, size_t index, char character)
6467 char string_pop_at(String* string, size_t index)
6568 {
6669 char tmp = string_at(string, index);
67- if(!tmp)
68- {
69- return '\0';
70- } else {
71- string_remove(string, index);
72- return tmp;
73- }
70+ string_remove(string, index);
71+ return tmp;
7472 }
7573
7674 bool string_concat(String* string, const String* other)
@@ -79,6 +77,7 @@ bool string_concat(String* string, const String* other)
7977 return false;
8078 memcpy(string->chars+string->length,other->chars,other->length);
8179 string->length += other->length;
80+ string->chars[string->length] = '\0';
8281 return true;
8382 }
8483
@@ -110,7 +109,10 @@ size_t string_count(const String* string, char character)
110109
111110 bool string_adjust_size(String* string, size_t size)
112111 {
113- while(string->capacity < size)
112+ if(size == SIZE_MAX && string->null_terminated)
113+ return false;
114+
115+ while(string->capacity < size+(string->null_terminated?1:0))
114116 {
115117 char* tmp = string->chars;
116118 string->chars = cutil_reallocarray_inc(string->chars, sizeof(*string->chars), string->capacity, string->capacity);
@@ -131,20 +133,22 @@ void delete_string(String* string)
131133 free(string);
132134 }
133135
134-String* from_cstring(const char* cstring)
136+String* from_cstring(const char* cstring, bool null_terminated)
135137 {
136- String* string = string_with_capacity(strlen(cstring));
138+ String* string = string_with_capacity(strlen(cstring), null_terminated);
137139 if(!string)
138140 {
139141 return NULL;
140142 } else {
141143 memcpy(string->chars, cstring, strlen(cstring));
142144 string->length = strlen(cstring);
145+ if(null_terminated)
146+ string->chars[string->length] = '\0';
143147 return string;
144148 }
145149 }
146150
147-String* from_cstring_reuse(char* cstring, size_t capacity)
151+String* from_cstring_reuse(char* cstring, size_t capacity, bool null_terminated)
148152 {
149153 String* string;
150154
@@ -161,9 +165,11 @@ String* from_cstring_reuse(char* cstring, size_t capacity)
161165 return string;
162166 }
163167
164-String* from_cstring_del(char* cstring)
168+String* from_cstring_del(char* cstring, bool null_terminated)
165169 {
166- String* ret = from_cstring(cstring);
170+ String* ret = from_cstring(cstring, null_terminated);
171+ if(!ret)
172+ return NULL;
167173 free(cstring);
168174 return ret;
169175 }
Msrc/test.c
@@ -71,66 +71,87 @@ static void test_string(void)
7171 String* string2;
7272 char* cstring;
7373 size_t tmp;
74+ bool truth;
7475
75- string = new_string();
76+ for(truth = false; truth == false || truth == true; truth++)
77+ {
78+ string = new_string(truth);
79+
80+ string_push(string, 'a');
81+ string_push(string, 'b');
82+ string_push(string, 'c');
83+ string_push(string, 'd');
84+ assert(string->length == 4);
85+
86+ cstring = to_cstring(string);
87+ assert(strcmp(cstring, "abcd") == 0);
88+ free(cstring);
89+
90+ string_remove(string, 3);
91+ cstring = to_cstring(string);
92+ assert(strcmp(cstring, "abc") == 0);
93+ free(cstring);
94+ assert(string->length == 3);
95+
96+ string_insert(string, 0,'a');
97+ cstring = to_cstring(string);
98+ assert(strcmp(cstring, "aabc") == 0);
99+ free(cstring);
100+ string2 = from_cstring("xyz", truth);
101+
102+ string_concat(string,string2);
103+ cstring = to_cstring(string);
104+ assert(strcmp(cstring, "aabcxyz") == 0);
105+ free(cstring);
106+
107+ delete_string(string2);
108+ delete_string(string);
109+
110+ string = from_cstring("abcd", truth);
111+ string2 = from_cstring("cd", truth);
112+ assert(string_find_str(string, string2, &tmp));
113+ assert(tmp == 2);
114+
115+ delete_string(string2);
116+ delete_string(string);
117+
118+ string = from_cstring("abcd", truth);
119+ assert(string->length == 4);
120+ string_remove_range(string, 0, string->length);
121+ assert(string->length == 0);
122+ delete_string(string);
123+
124+ string = from_cstring("bba", truth);
125+ string_strip(string, 'a');
126+ assert(string->length == 2);
127+
128+ cstring = to_cstring_del(string);
129+ free(cstring);
130+
131+
132+ string = from_cstring("asdyx782", truth);
133+ string2 = from_cstring("asdyx782", truth);
134+ assert(string_cmp(string, string2) == 0);
135+ delete_string(string2);
136+ delete_string(string);
137+ }
76138
139+ string = from_cstring("asdyx782", true);
77140 string_push(string, 'a');
78- string_push(string, 'b');
79- string_push(string, 'c');
80- string_push(string, 'd');
81- assert(string->length == 4);
82-
83- cstring = to_cstring(string);
84- assert(strcmp(cstring, "abcd") == 0);
85- free(cstring);
86-
87- string_remove(string, 3);
88- cstring = to_cstring(string);
89- assert(strcmp(cstring, "abc") == 0);
90- free(cstring);
91- assert(string->length == 3);
92-
93- string_insert(string, 0,'a');
94- cstring = to_cstring(string);
95- assert(strcmp(cstring, "aabc") == 0);
96- free(cstring);
97-
98- string2 = from_cstring("xyz");
99-
100- string_concat(string,string2);
101- cstring = to_cstring(string);
102- assert(strcmp(cstring, "aabcxyz") == 0);
103- free(cstring);
104-
105- delete_string(string2);
106- delete_string(string);
107-
108- string = from_cstring("abcd");
109- string2 = from_cstring("cd");
110- assert(string_find_str(string, string2, &tmp));
111- assert(tmp == 2);
141+ string_remove(string, 2);
142+ assert(strcmp(string->chars, "asyx782a") == 0);
143+ string_remove_range(string, 1, 7);
144+ assert(strcmp(string->chars, "a") == 0);
145+ assert(string_pop(string) == 'a');
146+ string2 = from_cstring("asdasdas", false);
147+ string_concat(string, string2);
148+ assert(strcmp(string->chars, "asdasdas") == 0);
112149
113150 delete_string(string2);
114- delete_string(string);
115-
116- string = from_cstring("abcd");
117- assert(string->length == 4);
118- string_remove_range(string, 0, string->length);
119- assert(string->length == 0);
120- delete_string(string);
151+ string2 = from_cstring("koasä_ #", true);
152+ string_move(string, string2);
153+ assert(strcmp(string->chars, "koasä_ #") == 0);
121154
122- string = from_cstring("bba");
123- string_strip(string, 'a');
124- assert(string->length == 2);
125-
126- cstring = to_cstring_del(string);
127- free(cstring);
128-
129-
130- string = from_cstring("asdyx782");
131- string2 = from_cstring("asdyx782");
132- assert(string_cmp(string, string2) == 0);
133- delete_string(string2);
134155 delete_string(string);
135156 }
136157