|
|
|
@ -11,6 +11,13 @@
|
|
|
|
|
#define FLAGSET(f, flag) (( (f) & (flag) ) == (flag))
|
|
|
|
|
#define DFLAGSET(f, flagname) FLAGSET(f, DISPF_SHOW_ ## flagname)
|
|
|
|
|
|
|
|
|
|
#define CMP(x,cmp,y) ( (x) cmp (y) ? (x) : (y) )
|
|
|
|
|
#define CMPx(x,cmp,y) ({ let _x = (x); let _y = (y); CMP(_x, cmp, _y); })
|
|
|
|
|
#define MIN(x, y) CMP((x), <, (y))
|
|
|
|
|
#define MINx(x, y) CMPx((x), <, (y))
|
|
|
|
|
#define MAX(x, y) CMP((x), >, (y))
|
|
|
|
|
#define MAXx(x, y) CMPx((x), >, (y))
|
|
|
|
|
|
|
|
|
|
// Returns number of bytes written to `dest`. Otherwise same as `strncpy()`.
|
|
|
|
|
static usize strncpy_n(char*pOUT dest, const char* restrict src, usize n)
|
|
|
|
|
{
|
|
|
|
@ -24,13 +31,19 @@ static usize strncpy_n(char*pOUT dest, const char* restrict src, usize n)
|
|
|
|
|
// Will not write past `dn` bytes of `dest`, will not read past `sn` bytes of `src`. Otherwise, same as `strncpy_n()`.
|
|
|
|
|
static usize s_strncpy_n(usize sn, usize dn; char dest[static pOUT dn], usize dn, const char src[static restrict sn], usize sn)
|
|
|
|
|
{
|
|
|
|
|
TODO("double-bounded strncpy");
|
|
|
|
|
usize i;
|
|
|
|
|
usize n = MIN(sn,dn);
|
|
|
|
|
for(i=0;i<n;i++)
|
|
|
|
|
if(! (*dest++ = *src++)) return i;
|
|
|
|
|
if(i<dn) dest[i] = 0;
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Will not write past `dn` bytes of `dest`, will not read past `sn` bytes of `src`. Otherwise, same as `strncat_n()`.
|
|
|
|
|
static usize s_strncat_n(usize sn, usize dn; char dest[static pOUT dn], usize dn, const char src[static restrict sn], usize sn)
|
|
|
|
|
static inline usize s_strncat_n(usize sn, usize dn; char dest[static pOUT dn], usize dn, const char src[static restrict sn], usize sn)
|
|
|
|
|
{
|
|
|
|
|
TODO("double-bounded strncat");
|
|
|
|
|
usize dl = MINx(strlen(dest), dn);
|
|
|
|
|
return s_strncpy_n(dest + dl, dn - dl, src, sn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Returns number of bytes written to (dest+strlen(dest)). Otherwise same as `strncat()`.
|
|
|
|
|