From 27cbe448f08a783196e49aa58d9af57240a20d43 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Tue, 26 Nov 2024 16:13:39 -0500 Subject: wstr: add wstr_find(), thread-safe wcs functions Signed-off-by: Andrew Opalach --- include/al/wstr.h | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/include/al/wstr.h b/include/al/wstr.h index 444cc32..1168e2d 100644 --- a/include/al/wstr.h +++ b/include/al/wstr.h @@ -23,9 +23,8 @@ typedef struct { #define al_wstr_w(w, i, n) (&((wstr){ ((u32)(n)), 0, &al_wstr_at(w, i) })) #define al_wstr_substr(w, start, end) al_wstr_w(w, start, ((end) - (start))) -#define AL_WSTR_FMT "%.*ls" -#define AL_WSTR_PRINTF(w) (w)->len, (w)->data -#define AL_WSTR_PRINTF_MAXLEN(w, l) AL_MIN((w)->len, (l)), (w)->data +#define AL_WSTR_FMT "%ls" +#define AL_WSTR_PRINTF(w) (w)->data AL_UNUSED_FUNCTION_PUSH @@ -75,10 +74,16 @@ static inline void al_wstr_clone(wstr *dest, wstr *src) static inline void al_wstr_from_cstr(wstr *w, char *c) { - size_t n = mbstowcs(NULL, c, 0) + 1; +#ifdef AL_HAVE_WIDE_STRING + mbstate_t mbstate = { 0 }; + size_t n = mbsrtowcs(NULL, (const char **)&c, 0, &mbstate) + 1; al_wstr_sized(w, n); - w->len = mbstowcs(w->data, c, n); + w->len = mbsrtowcs(w->data, (const char **)&c, n, &mbstate); w->data[w->len] = L'\0'; +#else + (void)c; + (void)w; +#endif } static inline void al_wstr_from_str(wstr *w, str *s) @@ -90,10 +95,17 @@ static inline void al_wstr_from_str(wstr *w, str *s) static inline void al_wstr_to_str(wstr *w, str *s) { - u32 len = (u32)wcstombs(NULL, w->data, 0); +#ifdef AL_HAVE_WIDE_STRING + mbstate_t mbstate = { 0 }; + u32 len = wcsrtombs(NULL, (const wchar_t **)&w->data, 0, &mbstate); al_str_sized(s, len); + // Excludes the null terminator. + wcsrtombs(s->data, (const wchar_t **)&w->data, len, &mbstate); s->len = len; - wcstombs(s->data, w->data, s->len); +#else + (void)s; + (void)w; +#endif } static inline s32 al_wstr_width(wstr *w) @@ -108,12 +120,28 @@ static inline s32 al_wstr_width(wstr *w) static inline s32 al_wstr_cmp(wstr *w, wstr *c, u32 start, u32 len) { +#ifdef AL_HAVE_WIDE_STRING return wcsncmp(&al_wstr_at(w, start), c->data, len); +#else + (void)w; + (void)c; + (void)start; + (void)len; + return 0; +#endif +} + +static inline s32 al_wstr_find(wstr *w, wchar_t c) +{ + for (s32 i = 0; i < (s32)w->len; i++) { + if (al_wstr_at(w, i) == c) return i; + } + return -1; } static inline s32 al_wstr_rfind(wstr *w, wchar_t c) { - for (s32 i = w->len - 1; i >= 0; i--) { + for (s32 i = (s32)w->len - 1; i >= 0; i--) { if (al_wstr_at(w, i) == c) return i; } return -1; -- cgit v1.2.3-101-g0448