Compare commits
8 Commits
master
...
display_fo
Author | SHA1 | Date |
---|---|---|
Avril | 4f428ea6db | 3 years ago |
Avril | 59439edefb | 3 years ago |
Avril | ee7434e8bf | 3 years ago |
Avril | aa94ab1622 | 3 years ago |
Avril | 0db8d882d0 | 3 years ago |
Avril | dca7e48d4a | 3 years ago |
Avril | eee5203ba9 | 3 years ago |
Avril | e9ccf5e2f2 | 3 years ago |
@ -0,0 +1,45 @@
|
|||||||
|
//! Better string handling
|
||||||
|
#ifndef _STR_H
|
||||||
|
#define _STR_H
|
||||||
|
|
||||||
|
#include <macros.h>
|
||||||
|
#include <ints.h>
|
||||||
|
|
||||||
|
#define STRF_OWNED AS(1ul << 5, int)
|
||||||
|
#define STRF_DERRIVED AS(1ul << 6, int)
|
||||||
|
enum str_ownership {
|
||||||
|
STR_NULL = 0,
|
||||||
|
|
||||||
|
STR_OWNED = STRF_OWNED,
|
||||||
|
STR_OWNED_STATIC,
|
||||||
|
STR_OWNED_MALLOC,
|
||||||
|
STR_OWNED_STACK,
|
||||||
|
|
||||||
|
STR_DERRIVED = STRF_DERRIVED,
|
||||||
|
STR_DERRIVED_STATIC,
|
||||||
|
STR_DERRIVED_MALLOC,
|
||||||
|
STR_DERRIVED_STACK,
|
||||||
|
};
|
||||||
|
|
||||||
|
//TODO: Complete rework
|
||||||
|
typedef struct string {
|
||||||
|
usize len, cap;
|
||||||
|
struct str_meta {
|
||||||
|
struct string* _shared derrived;
|
||||||
|
_Atomic usize refs;
|
||||||
|
void (*m_free)(void*);
|
||||||
|
|
||||||
|
enum str_ownership owned;
|
||||||
|
} meta;
|
||||||
|
union {
|
||||||
|
char* slice;
|
||||||
|
char str[];
|
||||||
|
};
|
||||||
|
} *str_t;
|
||||||
|
|
||||||
|
str_t* str_alloc(usize cap) _cconv(alloc);
|
||||||
|
char* str_new(const char* pIN cstr) _cconv(alloc);
|
||||||
|
|
||||||
|
void str_free(str_t* restrict str);
|
||||||
|
|
||||||
|
#endif /* _STR_H */
|
@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue