From a341dbc0ce456198d5773c7260e93e8433228ee2 Mon Sep 17 00:00:00 2001 From: Tyge Lovset Date: Sun, 29 May 2022 00:36:08 +0200 Subject: Renamed cstr_replace_first() => cstr_replace_one(). cstr.h now #include "utf8.h". Added iterator (utf8) to cstr and other utf8 functions postfixed by _u8(). Also renamed some utf8 functions in csview to better names. --- include/stc/ccommon.h | 2 ++ include/stc/cstr.h | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- include/stc/csview.h | 19 ++++++++----------- include/stc/forward.h | 9 ++++++--- include/stc/utf8.h | 29 ++++++++++++++++------------- 5 files changed, 81 insertions(+), 28 deletions(-) (limited to 'include') diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index a0fa58fb..46d53bc1 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -117,6 +117,8 @@ typedef const char* crawstr; #define crawstr_hash(p) c_strhash(*(p)) #define c_strlen_lit(literal) (sizeof "" literal - 1U) #define c_sv(lit) c_make(csview){lit, c_strlen_lit(lit)} +#define c_PRIsv ".*s" +#define c_ARGsv(sv) (int)(sv).size, (sv).str #define _c_ROTL(x, k) (x << (k) | x >> (8*sizeof(x) - (k))) diff --git a/include/stc/cstr.h b/include/stc/cstr.h index ca6d9392..1d57437e 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -32,6 +32,7 @@ #include "ccommon.h" #include "forward.h" +#include "utf8.h" #include /* malloc */ #include #include /* vsnprintf */ @@ -168,6 +169,53 @@ STC_INLINE size_t cstr_length(cstr s) STC_INLINE size_t cstr_capacity(cstr s) { return cstr_is_long(&s) ? cstr_l_cap(&s) : cstr_s_cap; } +// utf8: + +STC_INLINE size_t cstr_size_u8(cstr s) + { return utf8_size(cstr_str(&s)); } + +STC_INLINE size_t cstr_size_n_u8(cstr s, size_t nbytes) + { return utf8_size_n(cstr_str(&s), nbytes); } + +STC_INLINE csview cstr_at(const cstr* self, size_t bytepos) { + csview sv = cstr_sv(self); + sv.str += bytepos; + sv.size = utf8_codep_size(sv.str); + return sv; +} +STC_INLINE csview cstr_at_u8(const cstr* self, size_t u8idx) { + csview sv = cstr_sv(self); + sv.str = utf8_at(sv.str, u8idx); + sv.size = utf8_codep_size(sv.str); + return sv; +} + +STC_INLINE size_t cstr_pos_u8(const cstr* self, size_t u8idx) + { return utf8_pos(cstr_str(self), u8idx); } + +STC_INLINE bool cstr_valid_u8(const cstr* self) + { return utf8_valid(cstr_str(self)); } + +STC_INLINE utf8_decode_t cstr_peek(const cstr* self, size_t bytepos) { + utf8_decode_t d = {UTF8_OK}; + utf8_peek(cstr_str(self) + bytepos, &d); + return d; +} + +STC_INLINE cstr_iter cstr_begin(const cstr* self) { + const char* str = cstr_str(self); + return c_make(cstr_iter){.chr = {str, utf8_codep_size(str)}}; +} +STC_INLINE cstr_iter cstr_end(const cstr* self) { + csview sv = cstr_sv(self); + return c_make(cstr_iter){sv.str + sv.size}; +} +STC_INLINE void cstr_next(cstr_iter* it) { + it->ref += it->chr.size; + it->chr.size = utf8_codep_size(it->ref); +} + + STC_INLINE void cstr_clear(cstr* self) { _cstr_set_size(self, 0); } @@ -250,7 +298,7 @@ STC_INLINE void cstr_replace_n(cstr* self, size_t pos, size_t len, const char* r STC_INLINE void cstr_replace(cstr* self, size_t pos, size_t len, const char* repl) { cstr_replace_n(self, pos, len, repl, strlen(repl)); } -STC_INLINE size_t cstr_replace_first(cstr* self, size_t pos, const char* search, const char* repl) { +STC_INLINE size_t cstr_replace_one(cstr* self, size_t pos, const char* search, const char* repl) { pos = cstr_find_from(*self, pos, search); if (pos == cstr_npos) return pos; diff --git a/include/stc/csview.h b/include/stc/csview.h index 5bc25215..270a79f8 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -30,8 +30,6 @@ #define csview_null c_sv("") #define csview_new(literal) c_sv(literal) #define csview_npos (SIZE_MAX >> 1) -#define c_PRIsv ".*s" -#define c_ARGsv(sv) (int)(sv).size, (sv).str STC_API csview csview_substr(csview sv, intptr_t pos, size_t n); STC_API csview csview_slice(csview sv, intptr_t p1, intptr_t p2); @@ -64,23 +62,22 @@ STC_INLINE bool csview_ends_with(csview sv, csview sub) { if (sub.size > sv.size) return false; return !memcmp(sv.str + sv.size - sub.size, sub.str, sub.size); } STC_INLINE csview_iter csview_begin(const csview* self) - { return c_make(csview_iter){.codep = {self->str, utf8_codep_size(self->str)}}; } + { return c_make(csview_iter){.chr = {self->str, utf8_codep_size(self->str)}}; } STC_INLINE csview_iter csview_end(const csview* self) { return c_make(csview_iter){self->str + self->size}; } STC_INLINE void csview_next(csview_iter* it) - { it->ref += it->codep.size; it->codep.size = utf8_codep_size(it->ref); } + { it->ref += it->chr.size; it->chr.size = utf8_codep_size(it->ref); } /* utf8 */ -STC_INLINE bool utf8_valid_sv(csview sv) - { return utf8_size_n(sv.str, sv.size) != SIZE_MAX; } +STC_INLINE bool csview_valid_u8(csview sv) + { return utf8_valid_n(sv.str, sv.size); } -STC_INLINE size_t utf8_size_sv(csview sv) +STC_INLINE size_t csview_size_u8(csview sv) { return utf8_size_n(sv.str, sv.size); } -STC_INLINE csview utf8_substr(const char* str, size_t pos, size_t n) { - csview sv; - sv.str = utf8_at(str, pos); - sv.size = utf8_pos(sv.str, n); +STC_INLINE csview csview_substr_u8(csview sv, size_t u8pos, size_t u8len) { + sv.str = utf8_at(sv.str, u8pos); + sv.size = utf8_pos(sv.str, u8len); return sv; } diff --git a/include/stc/forward.h b/include/stc/forward.h index 635c63df..67f5f0f2 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -45,7 +45,7 @@ typedef struct { char* data; size_t size, cap; } cstr_buf; typedef char cstr_value; #if defined STC_CSTR_V1 - typedef struct cstr { char* str; } cstr; + typedef struct { char* str; } cstr; #else typedef union { struct { char data[sizeof(cstr_buf) - 1]; unsigned char last; } sml; @@ -53,9 +53,12 @@ typedef char cstr_value; } cstr; #endif -typedef struct csview { const char* str; size_t size; } csview; -typedef union csview_iter { const char *ref; csview codep; } csview_iter; +typedef struct { const char* str; size_t size; } csview; typedef char csview_value; +typedef union { + const char *ref; + csview chr; +} csview_iter, cstr_iter; #define c_true(...) __VA_ARGS__ #define c_false(...) diff --git a/include/stc/utf8.h b/include/stc/utf8.h index 02f24711..f11af046 100644 --- a/include/stc/utf8.h +++ b/include/stc/utf8.h @@ -13,9 +13,8 @@ int main() cstr_replace_sv(&s1, utf8_substr(cstr_str(&s1), 7, 1), c_sv("🐨")); printf("%s\n", cstr_str(&s1)); - csview sv = csview_from_s(s1); - c_foreach (i, csview, sv) - printf("%" c_PRIsv ",", c_ARGsv(i.codep)); + c_foreach (i, cstr, s1) + printf("%" c_PRIsv ",", c_ARGsv(i.chr)); } } // Output: @@ -54,19 +53,16 @@ STC_INLINE const char* utf8_at(const char *s, size_t index) { return s; } -STC_INLINE size_t utf8_pos(const char* s, size_t index) +STC_INLINE size_t utf8_pos(const char* s, size_t index) { return utf8_at(s, index) - s; } -STC_INLINE uint32_t utf8_peek(const char *s, unsigned* codep_size) { - utf8_decode_t d = {UTF8_OK}; - utf8_decode(&d, (uint8_t)*s++); - switch (d.size) { - case 4: utf8_decode(&d, (uint8_t)*s++); - case 3: utf8_decode(&d, (uint8_t)*s++); - case 2: utf8_decode(&d, (uint8_t)*s++); +STC_INLINE void utf8_peek(const char *s, utf8_decode_t* d) { + utf8_decode(d, (uint8_t)*s++); + switch (d->size) { + case 4: utf8_decode(d, (uint8_t)*s++); + case 3: utf8_decode(d, (uint8_t)*s++); + case 2: utf8_decode(d, (uint8_t)*s++); } - *codep_size = d.size; - return d.codep; } STC_INLINE unsigned utf8_codep_size(const char *s) { @@ -82,6 +78,13 @@ STC_INLINE bool utf8_valid(const char* s) { return d.state == UTF8_OK; } +STC_INLINE bool utf8_valid_n(const char* s, size_t n) { + utf8_decode_t d = {UTF8_OK}; + while ((n-- != 0) & (*s != 0)) + utf8_decode(&d, (uint8_t)*s++); + return d.state == UTF8_OK; +} + // --------------------------- IMPLEMENTATION --------------------------------- #ifdef i_implement // https://news.ycombinator.com/item?id=15423674 -- cgit v1.2.3