From 47c199b646a4205a8e8ff07397101398dea83221 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 5 Jul 2021 23:04:46 +0200 Subject: Some small updates. --- docs/cstr_api.md | 2 +- include/stc/ccommon.h | 28 +++++++++++++++------------- include/stc/cstr.h | 18 ++++++++++-------- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/docs/cstr_api.md b/docs/cstr_api.md index c26bb868..8c3c104f 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -83,7 +83,7 @@ cstr_iter_t cstr_end(cstr* self); void cstr_next(cstr_iter_t* it); bool cstr_getline(cstr *self, FILE *stream); // cstr_getdelim(self, '\n', stream) -bool cstr_getdelim(cstr *self, int delim, FILE *stream); +bool cstr_getdelim(cstr *self, int delim, FILE *stream); // does not append delim to result ``` Note that all methods with arguments `(..., const char* str, size_t n)`, `n` must be within the range of `str` length. diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 3713b444..7678a21d 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -51,17 +51,20 @@ # define STC_STATIC_ONLY(...) __VA_ARGS__ #endif -/* Macro overloading feature support: https://rextester.com/ONP80107 */ -#define _c_CAT( A, B ) A ## B -#define _c_SELECT(NAME, NUM) _c_CAT( NAME ## _, NUM) +/* Macro overloading feature support based on: https://rextester.com/ONP80107 */ +#define c_MACRO_OVERLOAD(name, ...) \ + _c_SELECT(name, _c_NUM_ARGS(__VA_ARGS__))(__VA_ARGS__) +#define _c_SELECT(name, num) _c_CONCAT(name ## _, num) +#define _c_CONCAT(a, b) a ## b +#define _c_NUM_ARGS(...) _c_APPLY_ARG_N((__VA_ARGS__, _c_RSEQ_N)) +#define _c_APPLY_ARG_N(args) _c_EXPAND(_c_ARG_N args) #define _c_EXPAND(...) __VA_ARGS__ -#define _c_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, N,...) N -#define _c_RSEQ_N 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 -#define _c_APPLY_ARG_N(ARGS) _c_EXPAND(_c_ARG_N ARGS) -#define _c_ARG_COUNT(...) _c_EXPAND(_c_APPLY_ARG_N((__VA_ARGS__, _c_RSEQ_N))) -#define _c_LABEL(id) _c_SELECT(_c_label_##id, __LINE__) +#define _c_RSEQ_N 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \ + 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 +#define _c_ARG_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \ + _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, \ + _23, _24, _25, _26, _27, _28, _29, _30, N, ...) N -#define c_MACRO_OVERLOAD(NAME, ...) _c_SELECT(NAME, _c_ARG_COUNT(__VA_ARGS__))(__VA_ARGS__) #define c_static_assert(cond, ...) typedef char _static_assert_[(cond) ? 1 : -1] #define c_container_of(ptr, type, member) \ ((type *)((char *)(ptr) - offsetof(type, member))) @@ -139,7 +142,7 @@ #define c_forbuffer(b, type, n) c_forbuffer_N(b, type, n, 256) #define c_forbuffer_N(b, type, n, BYTES) \ for (type _c_b[((BYTES) - 1) / sizeof(type) + 1], \ - *b = (n)*sizeof *b > (BYTES) ? c_new_n(type, n) : _c_b \ + *b = (n)*sizeof *b > (BYTES) ? c_new_n(type, n) : _c_b \ ; b; b != _c_b ? c_free(b) : (void)0, b = NULL) #define c_var(CX, c, ...) \ @@ -162,10 +165,9 @@ *(lo) = (uint64_t)_z, *(hi) = _z >> 64; } while(0) #elif defined(_MSC_VER) && defined(_WIN64) #include - #define c_umul128(a, b, lo, hi) (*(lo) = _umul128(a, b, hi), (void)0) + #define c_umul128(a, b, lo, hi) ((void)(*(lo) = _umul128(a, b, hi))) #elif defined(__x86_64__) #define c_umul128(a, b, lo, hi) \ - asm("mulq %[rhs]" : "=a" (*(lo)), "=d" (*(hi)) \ - : [lhs] "0" (a), [rhs] "rm" (b)) + asm("mulq %3" : "=a"(*(lo)), "=d"(*(hi)) : "a"(a), "rm"(b)) #endif #endif diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 6b5efd82..d5c2dd86 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -34,7 +34,7 @@ typedef struct { char* str; } cstr; typedef struct { char *ref; } cstr_iter_t; typedef char cstr_value_t; -#define cstr_npos INTPTR_MAX +#define cstr_npos (SIZE_MAX >> 1) STC_LIBRARY_ONLY( extern const cstr cstr_null; ) struct cstr_rep { size_t size, cap; char str[sizeof(size_t)]; }; @@ -49,7 +49,7 @@ typedef const char strlit_t[]; STC_API cstr cstr_from_n(const char* str, size_t n); STC_API cstr cstr_from_fmt(const char* fmt, ...); -STC_API cstr cstr_from_replace_all(const char* str, size_t str_len, +STC_API cstr cstr_from_replace_all(const char* str, size_t str_len, const char* find, size_t find_len, const char* repl, size_t repl_len); STC_API size_t cstr_reserve(cstr* self, size_t cap); @@ -74,6 +74,8 @@ STC_INLINE cstr cstr_init() { return cstr_null; } cstr_from_n(literal, sizeof c_make(strlit_t){literal} - 1) STC_INLINE cstr cstr_from(const char* str) { return cstr_from_n(str, strlen(str)); } +STC_INLINE const char* cstr_str(const cstr* self) { return self->str; } +STC_INLINE char* cstr_data(cstr* self) { return self->str; } STC_INLINE size_t cstr_size(cstr s) { return _cstr_rep(&s)->size; } STC_INLINE size_t cstr_length(cstr s) { return _cstr_rep(&s)->size; } STC_INLINE size_t cstr_capacity(cstr s) { return _cstr_rep(&s)->cap; } @@ -167,7 +169,7 @@ cstr_starts_with(cstr s, const char* sub) { STC_INLINE bool cstr_ends_with(cstr s, const char* sub) { size_t n = strlen(sub), sz = _cstr_rep(&s)->size; - return n <= sz ? memcmp(s.str + sz - n, sub, n) == 0 : false; + return n <= sz && !memcmp(s.str + sz - n, sub, n); } STC_INLINE bool @@ -179,7 +181,7 @@ cstr_istarts_with(cstr s, const char* sub) { STC_INLINE bool cstr_iends_with(cstr s, const char* sub) { size_t n = strlen(sub), sz = _cstr_rep(&s)->size; - return n <= sz ? c_strncasecmp(s.str + sz - n, sub, n) == 0 : false; + return n <= sz && !c_strncasecmp(s.str + sz - n, sub, n); } /* cvec/cmap adaption functions: */ @@ -317,7 +319,7 @@ cstr_replace_n(cstr* self, size_t pos, size_t len, const char* str, size_t n) { } STC_DEF cstr -cstr_from_replace_all(const char* str, size_t str_len, +cstr_from_replace_all(const char* str, size_t str_len, const char* find, size_t find_len, const char* repl, size_t repl_len) { cstr out = cstr_null; @@ -356,12 +358,12 @@ cstr_getdelim(cstr *self, int delim, FILE *fp) { if (c == EOF) return false; for (;;) { - if (pos == cap) - cap = cstr_reserve(self, (cap*13 >> 3) + 16); if (c == delim || c == EOF) { - self->str[_cstr_rep(self)->size = pos] = '\0'; + if (cap) self->str[_cstr_rep(self)->size = pos] = '\0'; return true; } + if (pos == cap) + cap = cstr_reserve(self, (cap*13 >> 3) + 16); self->str[pos++] = (char) c; c = fgetc(fp); } -- cgit v1.2.3