str_t impl: started `str_free()`
TODO: Walk derived string slice"s parent list, and free orphaned top-parent. (`str_free()` for derived string slices is more complex and is currently unimplemented, requiring list walking functions and full-offset computation during the walk.)
Fortune for naka's current commit: Future blessing − 末吉
_Atomicusizerefs;// Number of derrivations from this
_Atomicusizerefs;// Number of derrivations from this
void(*m_free)(void*);// How to free (when `_MALLOC`).
void(*m_free)(void*);// How to free (when `_MALLOC`).
_Atomicboolorphan;// If a `derive` references this parent somehow, but this string has been `str_free()`d. Tell the derived string that sets the `refs` to 0 to free it.
}owned;
}owned;
// `STRF_DERRIVED`
// `STRF_DERIVED`
struct{
structstr_meta_derived{
// String this is derrived from, can be either owned or derrived.
// String this is derived from, can be either owned or derived.
structstring*_sharedparent;
structstring*_sharedparent;
// `str`'s offset from `parent->str`.
// `str`'s offset from `parent->str`.
usizeoffset;
usizeoffset;
}derrived;
}derived;
}_inner;
}_inner;
}meta;
}meta;
// The start of this string slice. Regardless of slicing
// The start of this string slice. Regardless of slicing
@ -30,32 +31,88 @@ struct string {
//TODO: We can use offsetof() to reverse the result of `str_new()` from char* (str field) to str_t*.
//TODO: We can use offsetof() to reverse the result of `str_new()` from char* (str field) to str_t*.
// PTR_ASSIGNx always evaluates both args, so this is fine
PTR_ASSIGNx(owned,
_str_meta_parts_from(oship,&output,
&o_own,
&o_der)
);
switch(oship)
switch(oship)
{
{
caseSTR_OWNED_STACK:
caseSTR_OWNED_STATIC:
debug_assert(o_own);
*o_own=(structstr_meta_owned){
.refs=0,
.m_free=NULL,
.orphan=false,
};
break;
caseSTR_OWNED_MALLOC:
debug_assert(o_own);
*o_own=(structstr_meta_owned){
.refs=0,
.m_free=&free,
.orphan=false,
};
break;
caseSTR_DERIVED_STATIC:
caseSTR_DERIVED_STACK:
caseSTR_DERIVED_MALLOC:
debug_assert(o_der);
*o_der=(structstr_meta_derived){
.parent=NULL,
.offset=0,
};
break;
default:
ERROR("Cannot assign metadata from ownership type 0x%x, returning 0'd metadata",AS(oship,u32));
memset(&output,0,sizeof(output));
}
}
TODO("default str metadata");
returnoutput;
}
}
/// Allocates a bare new str_t. The metadata will be incomplete for `derived` string slices, and `str` will be `NULL`. For `owned` strings, `str` will be `calloc()`ed to `cap+1`.