apfl/src/strings.c

169 lines
3.4 KiB
C
Raw Normal View History

2021-12-10 20:22:16 +00:00
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "apfl.h"
#include "alloc.h"
#include "gc.h"
#include "internal.h"
2021-12-10 20:22:16 +00:00
#include "resizable.h"
struct apfl_string_view
apfl_string_view_from_view(struct apfl_string_view view)
{
return view;
}
struct apfl_string_view
apfl_string_view_from_cstr(char *cstr)
{
return (struct apfl_string_view) {
.bytes = cstr,
.len = strlen(cstr),
};
}
struct apfl_string_view
apfl_string_view_from_const_cstr(const char *cstr)
{
return (struct apfl_string_view) {
.bytes = cstr,
.len = strlen(cstr),
};
}
struct apfl_string_view
apfl_string_view_from_string(struct apfl_string string)
{
return (struct apfl_string_view) {
.bytes = string.bytes,
.len = string.len,
};
}
int
apfl_string_view_cmp(struct apfl_string_view a, struct apfl_string_view b)
{
size_t n = a.len > b.len ? b.len : a.len;
int cmp = memcmp(a.bytes, b.bytes, n);
if (cmp != 0) {
return cmp;
}
if (a.len == b.len) {
return 0;
}
return a.len > b.len ? 1 : -1;
}
struct apfl_string
apfl_string_blank(void)
{
return (struct apfl_string) {
.bytes = NULL,
.len = 0,
.cap = 0
};
}
2021-12-10 20:22:16 +00:00
void
apfl_string_deinit(struct apfl_allocator allocator, struct apfl_string *string)
2021-12-10 20:22:16 +00:00
{
FREE_BYTES(allocator, string->bytes, string->cap);
*string = apfl_string_blank();
2021-12-10 20:22:16 +00:00
}
bool
apfl_string_copy(struct apfl_allocator allocator, struct apfl_string *dst, struct apfl_string_view src)
2021-12-10 20:22:16 +00:00
{
apfl_string_deinit(allocator, dst);
if ((dst->bytes = ALLOC_BYTES(allocator, src.len)) == NULL) {
2021-12-10 20:22:16 +00:00
return false;
}
memcpy(dst->bytes, src.bytes, src.len);
dst->len = src.len;
dst->cap = src.len;
2021-12-10 20:22:16 +00:00
return true;
}
struct apfl_string
apfl_string_move(struct apfl_string *src)
{
struct apfl_string out = *src;
*src = apfl_string_blank();
2021-12-10 20:22:16 +00:00
return out;
}
static void
builder_reset(struct apfl_string_builder *builder)
2021-12-10 20:22:16 +00:00
{
apfl_resizable_init((void **)&(builder->bytes), &(builder->len), &(builder->cap));
}
void
apfl_string_builder_init(struct apfl_allocator allocator, struct apfl_string_builder *builder)
{
builder->allocator = allocator;
builder_reset(builder);
}
2021-12-10 20:22:16 +00:00
void
apfl_string_builder_deinit(struct apfl_string_builder *builder)
{
FREE_BYTES(builder->allocator, builder->bytes, builder->cap);
builder_reset(builder);
2021-12-10 20:22:16 +00:00
}
static bool
append_bytes(struct apfl_string_builder *builder, const char *bytes, size_t len)
{
return apfl_resizable_append(
builder->allocator,
2021-12-10 20:22:16 +00:00
sizeof(char),
APFL_RESIZABLE_ARGS(*builder, bytes),
bytes,
len
);
}
bool
apfl_string_builder_append(struct apfl_string_builder *builder, struct apfl_string_view view)
{
return append_bytes(builder, view.bytes, view.len);
}
bool
apfl_string_builder_append_byte(struct apfl_string_builder *builder, char byte)
{
return append_bytes(builder, &byte, 1);
}
struct apfl_string
apfl_string_builder_move_string(struct apfl_string_builder *builder)
{
struct apfl_string str;
str.bytes = builder->bytes;
str.len = builder->len;
str.cap = builder->cap;
2021-12-10 20:22:16 +00:00
builder_reset(builder);
2021-12-10 20:22:16 +00:00
return str;
}
struct apfl_string *
apfl_string_move_into_new_gc_string(struct gc *gc, struct apfl_string *in)
{
struct apfl_string *str = apfl_gc_new_string(gc);
if (str == NULL) {
return NULL;
}
*str = apfl_string_move(in);
return str;
}