codebased/common/string.c
2023-04-14 02:17:45 +02:00

103 lines
2.5 KiB
C

#include "common/string.h"
#include "common/panic.h"
#include "common/result.h"
#include <stddef.h>
#include <stdlib.h>
HeapString stringbuilder_build(StringBuilder* builder)
{
ASSERT(builder->length != 0, "builder cannot be empty");
if (*stringbuilder_get(builder, builder->length - 1) != '\0')
stringbuilder_append(builder, '\0');
return heapstring_from(builder->data, builder->length);
}
RESULT_CTORS(
HeapString, HeapString, UnescapeStringResult, unescaped_string_result
)
UnescapeStringResult common_unescape_string(StringView source)
{
StringBuilder builder;
stringbuilder_construct(&builder);
size_t i = 0;
while (i < source.length) {
if (source.data[i] == '\\') {
i++;
if (i >= source.length) {
stringbuilder_destroy(&builder);
return unescaped_string_result_ok(
heapstring_from_cstring("malformed escape sequence")
);
}
switch (source.data[i]) {
case '0':
stringbuilder_append(&builder, '\0');
break;
case 't':
stringbuilder_append(&builder, '\t');
break;
case 'r':
stringbuilder_append(&builder, '\r');
break;
case 'n':
stringbuilder_append(&builder, '\n');
break;
default:
stringbuilder_append(&builder, source.data[i]);
break;
}
} else {
stringbuilder_append(&builder, source.data[i]);
}
i++;
}
HeapString string = stringbuilder_build(&builder);
stringbuilder_destroy(&builder);
return unescaped_string_result_ok(string);
}
HeapString common_escape_string(StringView source)
{
StringBuilder builder;
stringbuilder_construct(&builder);
for (size_t i = 0; i < source.length; ++i) {
switch (source.data[i]) {
case '\0':
stringbuilder_append(&builder, '\\');
stringbuilder_append(&builder, '0');
break;
case '\t':
stringbuilder_append(&builder, '\\');
stringbuilder_append(&builder, 't');
break;
case '\r':
stringbuilder_append(&builder, '\\');
stringbuilder_append(&builder, 'r');
break;
case '\n':
stringbuilder_append(&builder, '\\');
stringbuilder_append(&builder, 'n');
break;
case '\\':
stringbuilder_append(&builder, '\\');
stringbuilder_append(&builder, '\\');
break;
case '\"':
stringbuilder_append(&builder, '\\');
stringbuilder_append(&builder, '\"');
break;
case '\'':
stringbuilder_append(&builder, '\\');
stringbuilder_append(&builder, '\'');
break;
default:
stringbuilder_append(&builder, source.data[i]);
break;
}
}
HeapString string = stringbuilder_build(&builder);
stringbuilder_destroy(&builder);
return string;
}