103 lines
2.5 KiB
C
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;
|
|
}
|