You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.3 KiB
67 lines
1.3 KiB
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <str.h>
|
|
|
|
static str_t _str_alloc_new(usize reserve)
|
|
{
|
|
return aligned_alloc(_Alignof(struct string), sizeof(struct string) + reserve + 1);
|
|
}
|
|
|
|
inline static str_t _str_unbox(str_t* restrict boxed)
|
|
{
|
|
str_t unboxed = *boxed;
|
|
free(boxed);
|
|
return unboxed;
|
|
}
|
|
|
|
_cconv(alloc) str_t* str_alloc(usize cap)
|
|
{
|
|
str_t unboxed = _str_alloc_new(cap);
|
|
unboxed->cap = cap;
|
|
unboxed->len = 0;
|
|
unboxed->meta = (struct str_meta){
|
|
.derrived = NULL,
|
|
.refs = 0,
|
|
.m_free = &free,
|
|
.owned = STR_OWNED_MALLOC,
|
|
};
|
|
memset(unboxed->str, 0, cap+1);
|
|
|
|
return box_value(unboxed);
|
|
}
|
|
|
|
void str_free(str_t* restrict str)
|
|
{
|
|
str_t ub = _str_unbox(str);
|
|
|
|
void* to_free = (void*)ub;
|
|
let _cont[] = { &&_done, &&_finish_free_derrived };
|
|
usize cont = 0;
|
|
switch(ub->meta.owned) {
|
|
case STR_DERRIVED_MALLOC:
|
|
ub->meta.derrived->meta.refs -=1;
|
|
to_free = NULL;
|
|
cont = 1;
|
|
case STR_OWNED_MALLOC:
|
|
//TODO: How to handle this refcounting?
|
|
if(ub->meta.refs > 0) WARN("Freeing referenced string");
|
|
//if(ub->meta.refs == 0)
|
|
if(to_free)
|
|
(ub->meta.m_free ?: &free)(to_free);
|
|
/*else {
|
|
ub->meta.refs -=1;
|
|
break;
|
|
}*/
|
|
goto _cont[cont];
|
|
_finish_free_derrived:
|
|
free(ub);
|
|
default:
|
|
_done:
|
|
break;
|
|
}
|
|
|
|
}
|