From 96d78ec2623b89089d3512f619fb252d1afc24a0 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 23 Feb 2021 23:50:05 +0100 Subject: Updated cstr doc. --- docs/cstr_api.md | 29 +++++++++++++---------- stc/clist.h | 8 ------- stc/cstr.h | 71 ++++++++++++++++++++++++++++---------------------------- 3 files changed, 52 insertions(+), 56 deletions(-) diff --git a/docs/cstr_api.md b/docs/cstr_api.md index dc4bb721..ae443087 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -1,7 +1,7 @@ # STC [cstr](../stc/cstr.h): String ![String](pics/string.jpg) -A **cstr* is an object that represent sequences of characters. It supports an interface similar to that of a standard container of bytes, but adding features specifically designed to operate with strings of single-byte characters. +A **cstr* object represent sequences of characters. It supports an interface similar to that of a standard container of bytes, but adding features specifically designed to operate with strings of single-byte characters, terminated by the null character. See the c++ class [std::basic_string](https://en.cppreference.com/w/cpp/string/basic_string) for a functional description. @@ -15,29 +15,31 @@ All cstr definitions and prototypes may be included in your C source file by inc ## Methods ```c -cstr cstr_init(void); // constructor +cstr cstr_init(void); // constructor cstr cstr_with_capacity(size_t cap); -cstr cstr_with_size(size_t len, char fill); // repeat fill len times +cstr cstr_with_size(size_t len, char fill); // repeat fill len times cstr cstr_from(const char* str); cstr cstr_from_n(const char* str, size_t len); -cstr cstr_from_fmt(const char* fmt, ...); // printf() formatting +cstr cstr_from_fmt(const char* fmt, ...); // printf() formatting + cstr cstr_clone(cstr s); -void cstr_del(cstr *self); // destructor +void cstr_del(cstr *self); // destructor + size_t cstr_size(cstr s); size_t cstr_length(cstr s); size_t cstr_capacity(cstr s); bool cstr_empty(cstr s); -char* cstr_front(cstr* self); -char* cstr_back(cstr* self); + size_t cstr_reserve(cstr* self, size_t capacity); void cstr_resize(cstr* self, size_t len, char fill); void cstr_clear(cstr* self); cstr* cstr_assign(cstr* self, const char* str); cstr* cstr_assign_n(cstr* self, const char* str, size_t len); -cstr* cstr_take(cstr* self, cstr s); // take the constructed or moved string -cstr cstr_move(cstr* self); // move string to caller, leave empty string +cstr* cstr_take(cstr* self, cstr s); // take the constructed or moved string +cstr cstr_move(cstr* self); // move string to caller, leave empty string + cstr* cstr_append(cstr* self, const char* str); -cstr* cstr_append_n(cstr* self, const char* str, size_t len); +cstr* cstr_append_n(cstr* self, const char* str, size_t len); // appends max len characters void cstr_push_back(cstr* self, char ch); void cstr_pop_back(cstr* self); void cstr_insert(cstr* self, size_t pos, const char* str); @@ -50,7 +52,7 @@ void cstr_replace_n(cstr* self, size_t pos, size_t len, const char* str, int cstr_compare(const cstr *s1, const cstr *s2); bool cstr_equals(cstr s, const char* str); bool cstr_equals_s(cstr s, cstr s2); -bool cstr_iequals(cstr s, const char* str); // prefix i = case-insensitive +bool cstr_iequals(cstr s, const char* str); // prefix i = case-insensitive size_t cstr_find(cstr s, const char* substr); size_t cstr_find_n(cstr s, const char* substr, size_t pos, size_t nlen); size_t cstr_ifind_n(cstr s, const char* substr, size_t pos, size_t nlen); @@ -61,12 +63,15 @@ bool cstr_ibegins_with(cstr s, const char* substr); bool cstr_ends_with(cstr s, const char* substr); bool cstr_iends_with(cstr s, const char* substr); +char* cstr_front(cstr* self); +char* cstr_back(cstr* self); + cstr_iter_t cstr_begin(cstr* self); cstr_iter_t cstr_end(cstr* self); void cstr_next(cstr_iter_t* it); char* cstr_itval(cstr_iter_t it); -bool cstr_getline(cstr *self, FILE *stream); // cstr_getdelim(self, '\n', stream) +bool cstr_getline(cstr *self, FILE *stream); // cstr_getdelim(self, '\n', stream) bool cstr_getdelim(cstr *self, int delim, FILE *stream); ``` ```c diff --git a/stc/clist.h b/stc/clist.h index bb2e2408..82fa6de2 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -83,14 +83,6 @@ int _state; \ } clist_##X##_iter_t -#define c_emplace_after(self, ctype, pos, ...) do { \ - ctype* __self = self; \ - ctype##_iter_t __pos = pos; \ - const ctype##_rawvalue_t __arr[] = __VA_ARGS__; \ - for (size_t __i=0; __istr, struct cstr_rep, str) +#define cstr_rep_(self) c_container_of((self)->str, struct cstr_rep, str) /* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */ #define _cstr_opt_mem(cap) ((((offsetof(struct cstr_rep, str) + (cap) + 8)>>4)<<4) + 8) /* optimal string capacity: 7, 23, 39, ... */ @@ -69,8 +69,8 @@ cstr_init() { return cstr_inits; } STC_INLINE void cstr_del(cstr_t* self) { - if (_cstr_rep(self)->cap) - c_free(_cstr_rep(self)); + if (cstr_rep_(self)->cap) + c_free(cstr_rep_(self)); } STC_INLINE cstr_t @@ -91,23 +91,23 @@ cstr_from(const char* str) { } STC_INLINE cstr_t cstr_clone(cstr_t s) { - return cstr_from_n(s.str, _cstr_rep(&s)->size); + return cstr_from_n(s.str, cstr_rep_(&s)->size); } STC_INLINE void cstr_clear(cstr_t* self) { - self->str[_cstr_rep(self)->size = 0] = '\0'; + self->str[cstr_rep_(self)->size = 0] = '\0'; } STC_INLINE char* cstr_front(cstr_t* self) {return self->str;} STC_INLINE char* -cstr_back(cstr_t* self) {return self->str + _cstr_rep(self)->size - 1;} +cstr_back(cstr_t* self) {return self->str + cstr_rep_(self)->size - 1;} STC_INLINE cstr_iter_t cstr_begin(cstr_t* self) {cstr_iter_t it = {self->str}; return it;} STC_INLINE cstr_iter_t cstr_end(cstr_t* self) { - cstr_iter_t it = {self->str + _cstr_rep(self)->size}; return it; + cstr_iter_t it = {self->str + cstr_rep_(self)->size}; return it; } STC_INLINE void cstr_next(cstr_iter_t* it) { ++it->ref; } STC_INLINE char* cstr_itval(cstr_iter_t it) {return it.ref;} @@ -119,8 +119,8 @@ cstr_assign(cstr_t* self, const char* str) { STC_INLINE cstr_t* cstr_take(cstr_t* self, cstr_t s) { - if (self->str != s.str && _cstr_rep(self)->cap) - c_free(_cstr_rep(self)); + if (self->str != s.str && cstr_rep_(self)->cap) + c_free(cstr_rep_(self)); self->str = s.str; return self; } @@ -141,7 +141,7 @@ cstr_push_back(cstr_t* self, char value) { } STC_INLINE void cstr_pop_back(cstr_t* self) { - self->str[ --_cstr_rep(self)->size ] = '\0'; + self->str[ --cstr_rep_(self)->size ] = '\0'; } STC_INLINE void @@ -167,13 +167,13 @@ cstr_getline(cstr_t *self, FILE *stream) { /* readonly */ STC_INLINE size_t -cstr_size(cstr_t s) {return _cstr_rep(&s)->size;} +cstr_size(cstr_t s) {return cstr_rep_(&s)->size;} STC_INLINE size_t -cstr_capacity(cstr_t s) {return _cstr_rep(&s)->cap;} +cstr_capacity(cstr_t s) {return cstr_rep_(&s)->cap;} STC_INLINE size_t -cstr_empty(cstr_t s) {return _cstr_rep(&s)->size == 0;} +cstr_empty(cstr_t s) {return cstr_rep_(&s)->size == 0;} STC_INLINE size_t -cstr_length(cstr_t s) { return _cstr_rep(&s)->size; } +cstr_length(cstr_t s) { return cstr_rep_(&s)->size; } STC_INLINE bool cstr_equals(cstr_t s1, const char* str) { @@ -208,12 +208,12 @@ cstr_ibegins_with(cstr_t s, const char* needle) { STC_INLINE bool cstr_ends_with(cstr_t s, const char* needle) { - size_t n = strlen(needle), sz = _cstr_rep(&s)->size; + size_t n = strlen(needle), sz = cstr_rep_(&s)->size; return n <= sz ? memcmp(s.str + sz - n, needle, n) == 0 : false; } STC_INLINE bool cstr_iends_with(cstr_t s, const char* needle) { - size_t n = strlen(needle), sz = _cstr_rep(&s)->size; + size_t n = strlen(needle), sz = cstr_rep_(&s)->size; return n <= sz ? c_strncasecmp(s.str + sz - n, needle, n) == 0 : false; } @@ -238,7 +238,7 @@ STC_LIBRARY_ONLY( static struct cstr_rep _cstr_nullrep = {0, 0, {0}}; STC_DEF size_t cstr_reserve(cstr_t* self, size_t cap) { - struct cstr_rep* rep = _cstr_rep(self); + struct cstr_rep* rep = cstr_rep_(self); size_t oldcap = rep->cap; if (cap > oldcap) { rep = (struct cstr_rep*) c_realloc(oldcap ? rep : NULL, _cstr_opt_mem(cap)); @@ -251,10 +251,10 @@ cstr_reserve(cstr_t* self, size_t cap) { STC_DEF void cstr_resize(cstr_t* self, size_t len, char fill) { - size_t n = _cstr_rep(self)->size; + size_t n = cstr_rep_(self)->size; cstr_reserve(self, len); if (len > n) memset(self->str + n, fill, len - n); - if (len | n) self->str[_cstr_rep(self)->size = len] = '\0'; + if (len | n) self->str[cstr_rep_(self)->size = len] = '\0'; } STC_DEF cstr_t @@ -281,7 +281,7 @@ cstr_vfmt(cstr_t* self, const char* fmt, va_list args) { int len = vsnprintf(NULL, (size_t)0, fmt, args); cstr_reserve(self, len); vsprintf(self->str, fmt, args2); - _cstr_rep(self)->size = len; + cstr_rep_(self)->size = len; va_end(args2); } @@ -308,10 +308,10 @@ cstr_from_fmt(const char* fmt, ...) { STC_DEF cstr_t* cstr_assign_n(cstr_t* self, const char* str, size_t len) { - if (len || _cstr_rep(self)->cap) { + if (len || cstr_rep_(self)->cap) { cstr_reserve(self, len); memmove(self->str, str, len); - self->str[_cstr_rep(self)->size = len] = '\0'; + self->str[cstr_rep_(self)->size = len] = '\0'; } return self; } @@ -319,15 +319,14 @@ cstr_assign_n(cstr_t* self, const char* str, size_t len) { STC_DEF cstr_t* cstr_append_n(cstr_t* self, const char* str, size_t len) { if (len) { - size_t oldlen = _cstr_rep(self)->size, newlen = oldlen + len; - if (newlen > _cstr_rep(self)->cap) { - /* handle self append */ - size_t off = (size_t) (str - self->str); + size_t oldlen = cstr_rep_(self)->size, newlen = oldlen + len; + if (newlen > cstr_rep_(self)->cap) { + size_t off = (size_t) (str - self->str); /* handle self append */ cstr_reserve(self, newlen*3/2); if (off <= oldlen) str = self->str + off; } memcpy(&self->str[oldlen], str, len); - self->str[_cstr_rep(self)->size = newlen] = '\0'; + self->str[cstr_rep_(self)->size = newlen] = '\0'; } return self; } @@ -335,11 +334,11 @@ cstr_append_n(cstr_t* self, const char* str, size_t len) { STC_INLINE void _cstr_internal_move(cstr_t* self, size_t pos1, size_t pos2) { if (pos1 == pos2) return; - size_t len = _cstr_rep(self)->size, newlen = len + pos2 - pos1; - if (newlen > _cstr_rep(self)->cap) + size_t len = cstr_rep_(self)->size, newlen = len + pos2 - pos1; + if (newlen > cstr_rep_(self)->cap) cstr_reserve(self, newlen*3/2); memmove(&self->str[pos2], &self->str[pos1], len - pos1); - self->str[_cstr_rep(self)->size = newlen] = '\0'; + self->str[cstr_rep_(self)->size = newlen] = '\0'; } STC_DEF void @@ -353,16 +352,16 @@ cstr_replace_n(cstr_t* self, size_t pos, size_t len, const char* str, size_t n) STC_DEF void cstr_erase_n(cstr_t* self, size_t pos, size_t n) { - size_t len = _cstr_rep(self)->size; + size_t len = cstr_rep_(self)->size; if (len) { memmove(&self->str[pos], &self->str[pos + n], len - (pos + n)); - self->str[_cstr_rep(self)->size -= n] = '\0'; + self->str[cstr_rep_(self)->size -= n] = '\0'; } } STC_DEF bool cstr_getdelim(cstr_t *self, int delim, FILE *fp) { - size_t pos = 0, cap = _cstr_rep(self)->cap; + size_t pos = 0, cap = cstr_rep_(self)->cap; int c = fgetc(fp); if (c == EOF) return false; @@ -370,7 +369,7 @@ cstr_getdelim(cstr_t *self, int delim, FILE *fp) { if (pos == cap) cap = cstr_reserve(self, cap*3/2 + 34); if (c == delim || c == EOF) { - self->str[_cstr_rep(self)->size = pos] = '\0'; + self->str[cstr_rep_(self)->size = pos] = '\0'; return true; } self->str[pos++] = (char) c; @@ -385,13 +384,13 @@ cstr_find(cstr_t s, const char* needle) { } STC_DEF size_t cstr_find_n(cstr_t s, const char* needle, size_t pos, size_t nlen) { - if (pos > _cstr_rep(&s)->size) return cstr_npos; + if (pos > cstr_rep_(&s)->size) return cstr_npos; char* res = c_strnfind(s.str + pos, needle, nlen); return res ? res - s.str : cstr_npos; } STC_DEF size_t cstr_ifind_n(cstr_t s, const char* needle, size_t pos, size_t nlen) { - if (pos > _cstr_rep(&s)->size) return cstr_npos; + if (pos > cstr_rep_(&s)->size) return cstr_npos; char* res = c_istrnfind(s.str + pos, needle, nlen); return res ? res - s.str : cstr_npos; } -- cgit v1.2.3