diff options
author | pommicket <pommicket@gmail.com> | 2023-10-15 15:23:58 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2023-10-15 15:23:58 -0400 |
commit | a01d4de1e2feda34a20bb8dd65ec76fef3c20d6b (patch) | |
tree | c24f71d8536663d6758a14194b50508041cc03ec /util.c | |
parent | 479219152b85b2cf12e5bfee6fdebca033355beb (diff) |
use reference-counted strings for string settings
this lets us remove the length limitations which were previously imposed
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 38 |
1 files changed, 38 insertions, 0 deletions
@@ -17,6 +17,42 @@ // on 16-bit systems, this is 16383. on 32/64-bit systems, this is 1073741823 // it is unusual to have a string that long. #define STRLEN_SAFE_MAX (UINT_MAX >> 2) +struct RcStr { + u32 ref_count; + char str[]; +}; + +RcStr *rc_str_new(const char *s, i64 len) { + if (len < 0) { + len = (i64)strlen(s); + } + RcStr *rc = calloc(1, sizeof(RcStr) + (size_t)len + 1); + assert(rc); + memcpy(rc->str, s, (size_t)len); + rc->ref_count = 1; + return rc; +} + +void rc_str_incref(RcStr *str) { + if (str) + str->ref_count += 1; +} + +void rc_str_decref(RcStr **pstr) { + RcStr *const str = *pstr; + if (!str) return; + str->ref_count -= 1; + if (str->ref_count == 0) { + *pstr = NULL; + free(str); + } +} + +const char *rc_str(RcStr *str, const char *default_value) { + if (!str) return default_value; + assert(str->ref_count > 0); + return str->str; +} bool is32_word(char32_t c) { return c > WCHAR_MAX || c == '_' || iswalnum((wint_t)c); @@ -151,6 +187,8 @@ bool str_has_path_prefix(const char *path, const char *prefix) { } bool streq(const char *a, const char *b) { + assert(a); + assert(b); return strcmp(a, b) == 0; } |