Compare commits

..

8 Commits

Author SHA1 Message Date
Avril 4f428ea6db
`TRANSMUTE()`: Fix input type size not being properly checked.
3 years ago
Avril 59439edefb
Merge `TRANSMUTE()` macro from branch ref: strings/87e102ded928dcc4d9c4c79e22c68b709ea91c40.
3 years ago
Avril ee7434e8bf Replace `Nx()` (temp value-assigning) macros with `Nv()` to avoid conflict with `TRACEx()` and for more clarity.
3 years ago
Avril aa94ab1622
Failed string API attempt. Branching for rework.
3 years ago
Avril 0db8d882d0
Attempted rewrite of _display_get_fmt()`, it currently doesn"t work. To compile using the old functional but (probably) unsafe function, pass `-D_DEBUG_USE_UNSAFE_DISPLAY_FMT_ARGS` in `CFLAGS`.
3 years ago
Avril dca7e48d4a
`s_strncpy_n()`, `s_strncat_n()` trivial implementation.
3 years ago
Avril eee5203ba9
Start: double-bounded string mutation functions.
3 years ago
Avril e9ccf5e2f2
Basic implementation of more sensible string mutating functions for display format string creation. (`strncat_n()`, `strncpy_n()`.)
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…
Cancel
Save