From 35167781cd4b34caca49a199154426a5ff48c46f Mon Sep 17 00:00:00 2001 From: tocariimaa Date: Thu, 30 Jan 2025 17:59:26 -0300 Subject: [PATCH] move string functions out from the header --- compiler/nstr.c | 76 ++++++++++++++++++++++++++++++++++++++++++++ compiler/pre.h | 83 ++++++------------------------------------------- 2 files changed, 86 insertions(+), 73 deletions(-) create mode 100644 compiler/nstr.c diff --git a/compiler/nstr.c b/compiler/nstr.c new file mode 100644 index 0000000..4e1b142 --- /dev/null +++ b/compiler/nstr.c @@ -0,0 +1,76 @@ +#include +#include + +#include "pre.h" + +int +vsnprintf(char *, unsigned long, const char *, va_list); + +/* Creates a `Str` from a buffer of size `len` */ +Str +Str_from_buf(u8 *buf, isize len) +{ + /* If this triggers an OOB, its because the code that created the string was + * broken anyways. ASan will catch it. */ + Assert(buf[len] == '\0'); + return (Str){ buf, len }; +} + +/* "Converts" a `Str` into a C string. Since `Str` are meant to be + * null-terminated already, no conversion is made, but ensures that the + * null terminator is present. */ +char * +Str_to_c(Str s) +{ + if (s.len == 0 || s.s == nil) + return nil; + Assert(s.s[s.len] == '\0'); + return (char *)s.s; +} + +/* Returns `true` if both strings are equal. */ +bool +Str_equal(Str s1, Str s2) +{ + /* because passing nil to mem* is UB even if size == 0... */ + return (s1.len == s2.len) && (s1.len == 0 || memcmp(s1.s, s2.s, s1.len) == 0); +} + +/* Heaps allocates a new `Str` of size `len`, with contents from `data` if it is + * not `nil`.*/ +Str +Str_new(const u8 *data, isize len) +{ + Assert(len >= 0); + Str s; + s.s = calloc(len + 1, sizeof(*s.s)); + s.len = len; + if (data != nil) { + memcpy(s.s, data, len); + s.s[len + 1] = '\0'; /* ensure */ + } + return s; +} + +/* Returns a formatted string (heap allocated) of the exact required size. */ +Str +Strafmt(const char *fmt, ...) +{ + Str s = {0}; + va_list args; + + va_start(args, fmt); + /* Calculate buffer size required to hold the formatted string */ + int reqs = vsnprintf(nil, 0, fmt, args); + va_end(args); + if (reqs < 0) + return s; + + s = Str_new(nil, reqs); + va_start(args, fmt); /* `vsnprintf` touched the arg list, reinitialize it */ + /* the nil terminator is guaranteed by `Str_new` */ + vsnprintf((char *)s.s, s.len + 1, fmt, args); + va_end(args); + + return s; +} diff --git a/compiler/pre.h b/compiler/pre.h index 74edaaf..7d33180 100644 --- a/compiler/pre.h +++ b/compiler/pre.h @@ -4,8 +4,6 @@ #include #include -#include -#include #include typedef int8_t i8; @@ -87,76 +85,15 @@ typedef struct { #define Str_empty(s) ((s).len == 0) #define Str_default(s, sor) (!Str_empty(s) ? (s) : (sor)) -int -vsnprintf(char *, unsigned long, const char *, va_list); - -/* Creates a `Str` from a buffer of size `len` */ -static inline Str -Str_from_buf(u8 *buf, isize len) -{ - /* If this triggers an OOB, its because the code that created the string was - * broken anyways. ASan will catch it. */ - Assert(buf[len] == '\0'); - return (Str){ buf, len }; -} - -/* "Converts" a `Str` into a C string. Since `Str` are meant to be - * null-terminated already, no conversion is made, but ensures that the - * null terminator is present. */ -static inline char * -Str_to_c(Str s) -{ - if (s.len == 0 || s.s == nil) - return nil; - Assert(s.s[s.len] == '\0'); - return (char *)s.s; -} - -/* Returns `true` if both strings are equal. */ -static inline bool -Str_equal(Str s1, Str s2) -{ - /* because passing nil to mem* is UB even if size == 0... */ - return (s1.len == s2.len) && (s1.len == 0 || memcmp(s1.s, s2.s, s1.len) == 0); -} - -/* Heaps allocates a new `Str` of size `len`, with contents from `data` if it is - * not `nil`.*/ -static inline Str -Str_new(const u8 *data, isize len) -{ - Assert(len >= 0); - Str s; - s.s = calloc(len + 1, sizeof(*s.s)); - s.len = len; - if (data != nil) { - memcpy(s.s, data, len); - s.s[len + 1] = '\0'; /* ensure */ - } - return s; -} - -/* Returns a formatted string (heap allocated) of the exact required size. */ -static inline Str -Strafmt(const char *fmt, ...) -{ - Str s = {0}; - va_list args; - - va_start(args, fmt); - /* Calculate buffer size required to hold the formatted string */ - int reqs = vsnprintf(nil, 0, fmt, args); - va_end(args); - if (reqs < 0) - return s; - - s = Str_new(nil, reqs); - va_start(args, fmt); /* `vsnprintf` touched the arg list, reinitialize it */ - /* the nil terminator is guaranteed by `Str_new` */ - vsnprintf((char *)s.s, s.len + 1, fmt, args); - va_end(args); - - return s; -} +Str +Str_from_buf(u8 *buf, isize len); +char * +Str_to_c(Str s); +bool +Str_equal(Str s1, Str s2); +Str +Str_new(const u8 *data, isize len); +Str +Strafmt(const char *fmt, ...); #endif