feat(common): Add support for replace in strbuf

This commit is contained in:
overflowerror 2024-05-17 23:07:33 +02:00
parent af20b29691
commit 6cce82a1ea
4 changed files with 101 additions and 3 deletions

View file

@ -6,7 +6,7 @@ AR = ar
ARFLAGS = rcs
OBJS = obj/alloc.o obj/dict.o obj/error.o obj/list.o
OBJS = obj/alloc.o obj/dict.o obj/error.o obj/list.o obj/strbuf.o
DEPS = $(OBJS:%.o=%.d)
-include $(DEPS)

33
common/src/strbuf.c Normal file
View file

@ -0,0 +1,33 @@
#include <string.h>
#include "strbuf.h"
strbuf_t strbuf_new(void) {
strbuf_t buffer = list_new(char);
list_add(buffer, '\0');
return buffer;
}
strbuf_t _strbuf_replace(strbuf_t buffer, char* needle, char* replace) {
size_t offset = 0;
size_t needle_length = strlen(needle);
size_t replace_length = strlen(replace);
char* result;
while((result = strstr(buffer + offset, needle)) != NULL) {
offset = result - buffer;
if (replace_length == needle_length) {
memcpy(result, replace, replace_length);
} else if (replace_length > needle_length) {
list_ensure_space(buffer, 1, replace_length - needle_length);
memmove(result + replace_length, result + needle_length, strlen(buffer) - offset - needle_length + 1);
memcpy(result, replace, replace_length);
} else {
memcpy(result, replace, replace_length);
memmove(result + replace_length, result + needle_length, strlen(buffer) - offset - needle_length + 1);
}
}
return buffer;
}

View file

@ -7,11 +7,9 @@
typedef char* strbuf_t;
#define strbuf_new() list_new(char)
#define strbuf_clear(b) { \
if (b == NULL) { \
b = strbuf_new(); \
list_add(b, '\0'); \
} else { \
list_header(b)->length = 1; \
b[0] = '\0'; \
@ -31,4 +29,13 @@ typedef char* strbuf_t;
list_header(b)->length += 1; \
}
#define strbuf_replace(b, n, r) { \
(b) = _strbuf_replace(b, n, r); \
}
strbuf_t strbuf_new(void);
strbuf_t _strbuf_replace(strbuf_t, char*, char*);
#define strbuf_free(b) list_free(b)
#endif

View file

@ -4,6 +4,7 @@
#include "list.h"
#include "dict.h"
#include "strbuf.h"
void test_list_add_remove_add(void) {
int* list = list_new(int);
@ -65,6 +66,58 @@ void test_dict_bug_duplicate_hash(void) {
assert_streq("foo", result, "value1 doesn't match");
}
void test_strbuf_allocation(void) {
strbuf_t buffer = strbuf_new();
assert_equals(1, list_size(buffer), "no space for null byte in empty buffer");
strbuf_append(buffer, "foo");
assert_equals(4, list_size(buffer), "no space for null byte after first append");
strbuf_append(buffer, "bar");
assert_equals(7, list_size(buffer), "no space for null byte after second append");
strbuf_free(buffer);
}
void test_strbuf_replace_equal_length(void) {
strbuf_t buffer = strbuf_new();
strbuf_append(buffer, "hello foo world foo !");
strbuf_replace(buffer, "foo", "bar");
assert_streq("hello bar world bar !", buffer, "buffer doesn't match");
printf("%lu, %zu\n", strlen(buffer), list_size(buffer));
assert_equals(strlen(buffer) + 1, list_size(buffer), "allocation doesn't match");
strbuf_free(buffer);
}
void test_strbuf_replace_shorter_length(void) {
strbuf_t buffer = strbuf_new();
strbuf_append(buffer, "hello foo world foo !");
strbuf_replace(buffer, "foo", "ba");
assert_streq("hello ba world ba !", buffer, "buffer doesn't match");
printf("%lu, %zu\n", strlen(buffer), list_size(buffer));
assert_equals(strlen(buffer) + 1 + 2, list_size(buffer), "allocation doesn't match");
strbuf_free(buffer);
}
void test_strbuf_replace_greater_length(void) {
strbuf_t buffer = strbuf_new();
strbuf_append(buffer, "hello foo world foo !");
strbuf_replace(buffer, "foo", "barr");
assert_streq("hello barr world barr !", buffer, "buffer doesn't match");
printf("%lu, %zu\n", strlen(buffer), list_size(buffer));
assert_equals(strlen(buffer) - 1, list_size(buffer), "allocation doesn't match");
strbuf_free(buffer);
}
int main(void) {
test_init();
@ -73,6 +126,11 @@ int main(void) {
test_run(test_dict_default);
test_run(test_dict_bug_duplicate_hash);
test_run(test_strbuf_allocation);
test_run(test_strbuf_replace_equal_length);
test_run(test_strbuf_replace_shorter_length);
test_run(test_strbuf_replace_greater_length);
if (test_results()) {
return 0;
} else {