From fde8f4a37c42a3611b544185806155a02e24227e Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 16 Feb 2022 23:33:58 +0100 Subject: Refactoring. Added size type param to forward_cmap/csmap . Reverted c_autovar macros. Added utf8_encode (not used yet). --- examples/new_map.c | 2 +- examples/new_smap.c | 2 +- examples/replace.c | 1 + include/stc/alt/csmap.h | 4 +- include/stc/ccommon.h | 22 +++++------ include/stc/cmap.h | 16 ++++---- include/stc/csmap.h | 2 +- include/stc/forward.h | 19 ++++----- include/stc/template.h | 6 ++- include/stc/utf8.h | 102 ++++++++++++++++++++++++++++++------------------ src/cregex.c | 2 +- 11 files changed, 100 insertions(+), 78 deletions(-) diff --git a/examples/new_map.c b/examples/new_map.c index 97fce008..a7008e4f 100644 --- a/examples/new_map.c +++ b/examples/new_map.c @@ -1,7 +1,7 @@ #include #include -forward_cmap(cmap_pnt, struct Point, int); +forward_cmap(cmap_pnt, struct Point, int, uint32_t); struct MyStruct { cmap_pnt pntmap; diff --git a/examples/new_smap.c b/examples/new_smap.c index 382d27ae..431f18c4 100644 --- a/examples/new_smap.c +++ b/examples/new_smap.c @@ -1,7 +1,7 @@ #include #include -forward_csmap(PMap, struct Point, int); +forward_csmap(PMap, struct Point, int, uint32_t); // Use forward declared PMap in struct struct MyStruct { diff --git a/examples/replace.c b/examples/replace.c index bc28cb2a..c425e4f8 100644 --- a/examples/replace.c +++ b/examples/replace.c @@ -1,5 +1,6 @@ #include +#include int main () { diff --git a/include/stc/alt/csmap.h b/include/stc/alt/csmap.h index 2909d813..840e684a 100644 --- a/include/stc/alt/csmap.h +++ b/include/stc/alt/csmap.h @@ -64,7 +64,7 @@ int main(void) { } #ifndef cx_forwarded - _c_aatree_types(_cx_self, C, i_key, i_val); + _c_aatree_types(_cx_self, C, i_key, i_val, i_size); #endif _c_aatree_complete_types(_cx_self, C); \ @@ -199,7 +199,7 @@ int main(void) { #if defined(_i_implement) -_c_aatree_types(csmap_SENTINEL, csmap_, int, int); +_c_aatree_types(csmap_SENTINEL, csmap_, int, int, i_size); _c_aatree_complete_types(csmap_SENTINEL, csmap_); static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_sentinel, 0}; diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index e9c21030..292ac9cc 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -168,27 +168,23 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle, size_t slen, cons for (type i=start, _c_inc=step, _c_end=(stop) - (0 < _c_inc) \ ; (i <= _c_end) == (0 < _c_inc); i += _c_inc) -#define c_autovar(...) c_MACRO_OVERLOAD(c_autovar, __VA_ARGS__) -#define c_autovar2(declvar, drop) for (declvar, **_c_ii = NULL; !_c_ii; ++_c_ii, drop) -#define c_autovar3(declvar, ok, drop) for (declvar, **_c_ii = NULL; !_c_ii && (ok); ++_c_ii, drop) -#define c_autoscope(...) c_MACRO_OVERLOAD(c_autoscope, __VA_ARGS__) -#define c_autoscope2(init, drop) for (int _c_ii = (init, 0); !_c_ii; ++_c_ii, drop) -#define c_autoscope3(init, ok, drop) for (int _c_ii = (init, 0); !_c_ii && (ok); ++_c_ii, drop) +#define c_autovar(declvar, ...) for (declvar, **_c_ii = NULL; !_c_ii; ++_c_ii, __VA_ARGS__) +#define c_autoscope(init, ...) for (int _c_ii = (init, 0); !_c_ii; ++_c_ii, __VA_ARGS__) #define c_autodefer(...) for (int _c_ii = 0; !_c_ii; ++_c_ii, __VA_ARGS__) #define c_breakauto continue #define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__) #define c_auto2(C, a) \ - c_autovar2(C a = C##_init(), C##_drop(&a)) + c_autovar(C a = C##_init(), C##_drop(&a)) #define c_auto3(C, a, b) \ - c_autovar2(c_EXPAND(C a = C##_init(), b = C##_init()), \ - c_EXPAND(C##_drop(&b), C##_drop(&a))) + c_autovar(c_EXPAND(C a = C##_init(), b = C##_init()), \ + C##_drop(&b), C##_drop(&a)) #define c_auto4(C, a, b, c) \ - c_autovar2(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init()), \ - c_EXPAND(C##_drop(&c), C##_drop(&b), C##_drop(&a))) + c_autovar(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init()), \ + C##_drop(&c), C##_drop(&b), C##_drop(&a)) #define c_auto5(C, a, b, c, d) \ - c_autovar2(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ - c_EXPAND(C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a))) + c_autovar(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ + C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a)) #define c_autobuf(b, type, n) c_autobuf_N(b, type, n, 256) #define c_autobuf_N(b, type, n, BYTES) \ diff --git a/include/stc/cmap.h b/include/stc/cmap.h index d4040e57..af247ffc 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -54,7 +54,7 @@ int main(void) { #include #include #define _cmap_inits {NULL, NULL, 0, 0, 0.85f} -typedef struct { MAP_SIZE_T idx; uint8_t hx; } chash_bucket_t; +typedef struct { size_t idx; uint8_t hx; } chash_bucket_t; #endif // CMAP_H_INCLUDED #ifndef _i_prefix @@ -71,7 +71,7 @@ typedef struct { MAP_SIZE_T idx; uint8_t hx; } chash_bucket_t; #endif #include "template.h" #if !c_option(c_is_fwd) -_cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, _i_MAP_ONLY, _i_SET_ONLY); +_cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, i_size, _i_MAP_ONLY, _i_SET_ONLY); #endif _i_MAP_ONLY( struct _cx_value { @@ -289,15 +289,15 @@ STC_DEF chash_bucket_t _cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr) { const uint64_t _hash = i_hash(rkeyptr, sizeof *rkeyptr); uint8_t _hx; _cx_size _cap = self->bucket_count; - chash_bucket_t b = {c_PASTE(fastrange_,MAP_SIZE_T)(_hash, _cap), (uint8_t)(_hash | 0x80)}; + chash_bucket_t b = {c_PASTE(fastrange_,i_size)(_hash, _cap), (uint8_t)(_hash | 0x80)}; const uint8_t* _hashx = self->_hashx; while ((_hx = _hashx[b.idx])) { if (_hx == b.hx) { _cx_rawkey _raw = i_keyto(_i_keyref(self->table + b.idx)); if (i_eq(&_raw, rkeyptr)) break; } - _cx_size _mask = (_cx_size) -(++b.idx != _cap); - b.idx &= _mask; // b.idx = (b.idx + 1) % _cap + if (++b.idx == _cap) + b.idx = 0; } return b; } @@ -368,12 +368,12 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) { uint8_t* _hashx = self->_hashx; _cx_memb(_value_drop)(&_slot[i]); for (;;) { /* delete without leaving tombstone */ - _cx_size _mask = (_cx_size) -(++j != _cap); - j &= _mask; + if (++j == _cap) + j = 0; if (! _hashx[j]) break; _cx_rawkey _raw = i_keyto(_i_keyref(_slot + j)); - k = c_PASTE(fastrange_,MAP_SIZE_T)(i_hash(&_raw, sizeof _raw), _cap); + k = c_PASTE(fastrange_,i_size)(i_hash(&_raw, sizeof _raw), _cap); if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */ _slot[i] = _slot[j], _hashx[i] = _hashx[j], i = j; } diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 067bfd64..c360df08 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -74,7 +74,7 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; #include "template.h" #if !c_option(c_is_fwd) -_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, _i_MAP_ONLY, _i_SET_ONLY); +_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, i_size, _i_MAP_ONLY, _i_SET_ONLY); #endif _i_MAP_ONLY( struct _cx_value { diff --git a/include/stc/forward.h b/include/stc/forward.h index 0a14ad93..ca1fd540 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -29,10 +29,10 @@ #define forward_carr3(CX, VAL) _c_carr3_types(CX, VAL) #define forward_cdeq(CX, VAL) _c_cdeq_types(CX, VAL) #define forward_clist(CX, VAL) _c_clist_types(CX, VAL) -#define forward_cmap(CX, KEY, VAL) _c_chash_types(CX, KEY, VAL, c_true, c_false) -#define forward_csmap(CX, KEY, VAL) _c_aatree_types(CX, KEY, VAL, c_true, c_false) -#define forward_cset(CX, KEY) _c_chash_types(CX, cset, KEY, KEY, c_false, c_true) -#define forward_csset(CX, KEY) _c_aatree_types(CX, KEY, KEY, c_false, c_true) +#define forward_cmap(CX, KEY, VAL, SZ) _c_chash_types(CX, KEY, VAL, SZ, c_true, c_false) +#define forward_csmap(CX, KEY, VAL, SZ) _c_aatree_types(CX, KEY, VAL, SZ, c_true, c_false) +#define forward_cset(CX, KEY, SZ) _c_chash_types(CX, cset, KEY, KEY, SZ, c_false, c_true) +#define forward_csset(CX, KEY, SZ) _c_aatree_types(CX, KEY, KEY, SZ, c_false, c_true) #define forward_cbox(CX, VAL) _c_cbox_types(CX, VAL) #define forward_carc(CX, VAL) _c_carc_types(CX, VAL) #define forward_cpque(CX, VAL) _c_cpque_types(CX, VAL) @@ -47,9 +47,6 @@ typedef struct csview { const char* str; size_t size; } csview; typedef union csview_iter { const char *ref; csview cp; } csview_iter; typedef char csview_value; -#ifndef MAP_SIZE_T -#define MAP_SIZE_T uint32_t -#endif #define c_true(...) __VA_ARGS__ #define c_false(...) @@ -81,10 +78,10 @@ typedef char csview_value; SELF##_node *last; \ } SELF -#define _c_chash_types(SELF, KEY, VAL, MAP_ONLY, SET_ONLY) \ +#define _c_chash_types(SELF, KEY, VAL, SZ, MAP_ONLY, SET_ONLY) \ typedef KEY SELF##_key; \ typedef VAL SELF##_mapped; \ - typedef MAP_SIZE_T SELF##_size_t; \ + typedef SZ SELF##_size_t; \ \ typedef SET_ONLY( SELF##_key ) \ MAP_ONLY( struct SELF##_value ) \ @@ -107,10 +104,10 @@ typedef char csview_value; float max_load_factor; \ } SELF -#define _c_aatree_types(SELF, KEY, VAL, MAP_ONLY, SET_ONLY) \ +#define _c_aatree_types(SELF, KEY, VAL, SZ, MAP_ONLY, SET_ONLY) \ typedef KEY SELF##_key; \ typedef VAL SELF##_mapped; \ - typedef MAP_SIZE_T SELF##_size_t; \ + typedef SZ SELF##_size_t; \ typedef struct SELF##_node SELF##_node; \ \ typedef SET_ONLY( SELF##_key ) \ diff --git a/include/stc/template.h b/include/stc/template.h index d5291eaa..c61aded4 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -44,13 +44,16 @@ #define i_type i_cnt #error "i_cnt and i_equ no longer supported: use new name i_type / i_eq" #endif - #ifdef i_type #define i_tag i_type #undef _i_prefix #define _i_prefix #endif +#ifndef i_size + #define i_size uint32_t +#endif + #if defined i_key_str || defined i_val_str #include "cstr.h" #endif @@ -236,6 +239,7 @@ #undef i_keyfrom #undef i_keyto #undef i_keydrop +#undef i_size #undef _i_prefix #undef _i_no_raw diff --git a/include/stc/utf8.h b/include/stc/utf8.h index 3f679654..60599519 100644 --- a/include/stc/utf8.h +++ b/include/stc/utf8.h @@ -29,11 +29,12 @@ enum { UTF8_OK = 0, UTF8_ERROR = 4 }; typedef struct { uint32_t state, codep, len; } utf8_decode_t; /* decode next utf8 codepoint. */ -STC_API uint32_t utf8_decode(utf8_decode_t *c, const uint8_t b); -STC_API const uint8_t* utf8_nextc(utf8_decode_t *c, const uint8_t* s); -STC_API size_t utf8_size(const char *s); -STC_API size_t utf8_size_n(const char *s, size_t n); -STC_API const char* utf8_at(const char *s, size_t index); +STC_API size_t utf8_encode(char *out, uint32_t c); +STC_API uint32_t utf8_decode(utf8_decode_t *d, const uint8_t b); +STC_API const uint8_t* utf8_next(utf8_decode_t *d, const uint8_t* u); +STC_API size_t utf8_size(const char *s); +STC_API size_t utf8_size_n(const char *s, size_t n); +STC_API const char* utf8_at(const char *s, size_t index); STC_INLINE size_t utf8_pos(const char* s, size_t index) { return utf8_at(s, index) - s; } @@ -42,15 +43,15 @@ STC_INLINE bool utf8_valid(const char* s) { return utf8_size(s) != SIZE_MAX; } STC_INLINE uint32_t utf8_peek(const char *s) { - utf8_decode_t ctx = {UTF8_OK, 0}; - utf8_nextc(&ctx, (const uint8_t*)s); - return ctx.codep; + utf8_decode_t d = {UTF8_OK, 0}; + utf8_next(&d, (const uint8_t*)s); + return d.codep; } STC_INLINE size_t utf8_codep_size(const char *s) { - utf8_decode_t ctx = {UTF8_OK, 0}; - utf8_nextc(&ctx, (const uint8_t*)s); - return ctx.len; + utf8_decode_t d = {UTF8_OK, 0}; + utf8_next(&d, (const uint8_t*)s); + return d.len; } // --------------------------- IMPLEMENTATION --------------------------------- @@ -58,60 +59,83 @@ STC_INLINE size_t utf8_codep_size(const char *s) { // https://news.ycombinator.com/item?id=15423674 // https://gist.github.com/s4y/344a355f8c1f99c6a4cb2347ec4323cc -STC_DEF uint32_t utf8_decode(utf8_decode_t *c, const uint8_t b) +STC_DEF uint32_t utf8_decode(utf8_decode_t *d, const uint8_t b) { - switch (c->state) { + switch (d->state) { case UTF8_OK: - if (b < 0x80) c->codep = b, c->len = 1; - else if (b < 0xc2) c->state = UTF8_ERROR; - else if (b < 0xe0) c->state = 1, c->codep = b & 0x1f, c->len = 2; - else if (b < 0xf0) c->state = 2, c->codep = b & 0xf, c->len = 3; - else if (b < 0xf5) c->state = 3, c->codep = b & 0x7, c->len = 4; - else c->state = UTF8_ERROR; + if (b < 0x80) d->codep = b, d->len = 1; + else if (b < 0xC2) d->state = UTF8_ERROR, d->len = 0; + else if (b < 0xE0) d->state = 1, d->codep = b & 0x1F, d->len = 2; + else if (b < 0xF0) d->state = 2, d->codep = b & 0x0F, d->len = 3; + else if (b < 0xF5) d->state = 3, d->codep = b & 0x07, d->len = 4; + else d->state = UTF8_ERROR, d->len = 0; break; case 1: case 2: case 3: - if ((b & 0xc0) == 0x80) { - c->state -= 1; - c->codep = (c->codep << 6) | (b & 0x3f); + if ((b & 0xC0) == 0x80) { + d->state -= 1; + d->codep = (d->codep << 6) | (b & 0x3F); } else - c->state = UTF8_ERROR; + d->state = UTF8_ERROR, d->len = 0; } - return c->state; + return d->state; } -STC_DEF const uint8_t* utf8_nextc(utf8_decode_t *c, const uint8_t* s) { - utf8_decode(c, *s++); - switch (c->len) { - case 4: utf8_decode(c, *s++); - case 3: utf8_decode(c, *s++); - case 2: utf8_decode(c, *s++); +STC_DEF size_t utf8_encode(char *out, uint32_t c) +{ + char* p = out; + if (c < 0x80U) { + *p++ = (char) c; + } else if (c < 0x0800U) { + *p++ = (char) ((c>>6 & 0x1F) | 0xC0); + *p++ = (char) ((c & 0x3F) | 0x80); + } else if (c < 0x010000U) { + if (c < 0xD800U || c >= 0xE000U) { + *p++ = (char) ((c>>12 & 0x0F) | 0xE0); + *p++ = (char) ((c>>6 & 0x3F) | 0x80); + *p++ = (char) ((c & 0x3F) | 0x80); + } + } else if (c < 0x110000U) { + *p++ = (char) ((c>>18 & 0x07) | 0xF0); + *p++ = (char) ((c>>12 & 0x3F) | 0x80); + *p++ = (char) ((c>>6 & 0x3F) | 0x80); + *p++ = (char) ((c & 0x3F) | 0x80); } - return s; + return p - out; +} + +STC_DEF const uint8_t* utf8_next(utf8_decode_t *d, const uint8_t* u) { + utf8_decode(d, *u++); + switch (d->len) { + case 4: utf8_decode(d, *u++); + case 3: utf8_decode(d, *u++); + case 2: utf8_decode(d, *u++); + } + return u; } STC_DEF size_t utf8_size(const char *s) { - utf8_decode_t ctx = {UTF8_OK, 0}; + utf8_decode_t d = {UTF8_OK, 0}; size_t size = 0; while (*s) - size += !utf8_decode(&ctx, (uint8_t)*s++); - return !ctx.state ? size : SIZE_MAX; + size += !utf8_decode(&d, (uint8_t)*s++); + return d.state ? SIZE_MAX : size; } STC_DEF size_t utf8_size_n(const char *s, size_t n) { - utf8_decode_t ctx = {UTF8_OK, 0}; + utf8_decode_t d = {UTF8_OK, 0}; size_t size = 0; while ((n-- != 0) & (*s != 0)) - size += !utf8_decode(&ctx, (uint8_t)*s++); - return !ctx.state ? size : SIZE_MAX; + size += !utf8_decode(&d, (uint8_t)*s++); + return !d.state ? size : SIZE_MAX; } STC_DEF const char* utf8_at(const char *s, size_t index) { - utf8_decode_t ctx = {UTF8_OK, 0}; + utf8_decode_t d = {UTF8_OK, 0}; for (size_t i = 0; (i < index) & (*s != 0); ++s) - i += !utf8_decode(&ctx, (uint8_t)*s); + i += !utf8_decode(&d, (uint8_t)*s); return s; } diff --git a/src/cregex.c b/src/cregex.c index 7583e900..804e8047 100644 --- a/src/cregex.c +++ b/src/cregex.c @@ -1009,7 +1009,7 @@ regexec1(const Reprog *progp, /* program to run */ if (s == j->eol || r == 0) continue; break; case EOZ: - if (s == j->eol || r == 0 || r == '\n' && s[1] == 0) continue; + if (s == j->eol || r == 0 || (r == '\n' && s[1] == 0)) continue; break; case NWBOUND: ok = true; -- cgit v1.2.3