diff options
| -rw-r--r-- | docs/cstr_api.md | 26 | ||||
| -rw-r--r-- | docs/csubstr_api.md | 83 | ||||
| -rw-r--r-- | docs/csview_api.md | 8 | ||||
| -rw-r--r-- | include/stc/ccommon.h | 4 | ||||
| -rw-r--r-- | include/stc/cstr.h | 5 | ||||
| -rw-r--r-- | include/stc/csubstr.h | 5 | ||||
| -rw-r--r-- | include/stc/csview.h | 12 | ||||
| -rw-r--r-- | misc/examples/strings/sso_substr.c | 6 |
8 files changed, 74 insertions, 75 deletions
diff --git a/docs/cstr_api.md b/docs/cstr_api.md index 36606b76..07b9b4c8 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -22,7 +22,8 @@ cstr cstr_init(void); // construct cstr cstr_lit(const char literal_only[]); // cstr from literal; no strlen() call. cstr cstr_from(const char* str); // constructor using strlen() cstr cstr_from_n(const char* str, intptr_t n); // constructor with n first bytes of str -cstr cstr_from_ss(csubstr sv); // construct cstr from csubstr +cstr cstr_from_sv(csview sv); // construct cstr from csview +cstr cstr_from_ss(csubstr ss); // construct cstr from csubstr cstr cstr_with_capacity(intptr_t cap); cstr cstr_with_size(intptr_t len, char fill); // repeat fill len times cstr cstr_from_fmt(const char* fmt, ...); // printf() formatting @@ -32,10 +33,11 @@ cstr* cstr_take(cstr* self, cstr s); // take owne cstr cstr_move(cstr* self); // move string to caller, leave self empty void cstr_drop(cstr* self); // destructor -const char* cstr_str(const cstr* self); // cast to const char* -char* cstr_data(cstr* self); // cast to mutable char* -csubstr cstr_ss(const cstr* self); // cast to string view -cstr_buf cstr_buffer(cstr* self); // cast to mutable buffer (with capacity) +const char* cstr_str(const cstr* self); // to const char* +csview cstr_sv(const cstr* self); // to csview +csubstr cstr_ss(const cstr* self); // to csubstr +char* cstr_data(cstr* self); // to mutable char* +cstr_buf cstr_buffer(cstr* self); // to mutable buffer (with capacity) intptr_t cstr_size(const cstr* self); intptr_t cstr_capacity(const cstr* self); @@ -48,7 +50,7 @@ void cstr_clear(cstr* self); char* cstr_assign(cstr* self, const char* str); char* cstr_assign_n(cstr* self, const char* str, intptr_t n); // assign n first bytes of str -char* cstr_assign_ss(cstr* self, csubstr sv); +char* cstr_assign_ss(cstr* self, csubstr ss); char* cstr_copy(cstr* self, cstr s); // copy-assign a cstr int cstr_printf(cstr* self, const char* fmt, ...); // source and target must not overlap. @@ -75,7 +77,7 @@ void cstr_replace_at_ss(cstr* self, intptr_t pos, intptr_t len, const csu void cstr_replace_at_s(cstr* self, intptr_t pos, intptr_t len, cstr repl); bool cstr_equals(const cstr* self, const char* str); -bool cstr_equals_ss(const cstr* self, csubstr sv); +bool cstr_equals_ss(const cstr* self, csubstr ss); bool cstr_equals_s(const cstr* self, cstr s); intptr_t cstr_find(const cstr* self, const char* search); @@ -83,11 +85,11 @@ intptr_t cstr_find_at(const cstr* self, intptr_t pos, const char* search); // bool cstr_contains(const cstr* self, const char* search); bool cstr_starts_with(const cstr* self, const char* str); -bool cstr_starts_with_ss(const cstr* self, csubstr sv); +bool cstr_starts_with_ss(const cstr* self, csubstr ss); bool cstr_starts_with_s(const cstr* self, cstr s); bool cstr_ends_with(const cstr* self, const char* str); -bool cstr_ends_with_ss(const cstr* self, csubstr sv); +bool cstr_ends_with_ss(const cstr* self, csubstr ss); bool cstr_ends_with_s(const cstr* self, cstr s); bool cstr_getline(cstr *self, FILE *stream); // cstr_getdelim(self, '\n', stream) @@ -112,14 +114,14 @@ cstr_iter cstr_advance(cstr_iter it, intptr_t n); // utf8 functions requires linking with src/utf8code.c symbols: bool cstr_valid_utf8(const cstr* self); // check if str is valid utf8 -cstr cstr_casefold_ss(csubstr sv); // returns new casefolded utf8 cstr +cstr cstr_casefold_ss(csubstr ss); // returns new casefolded utf8 cstr cstr cstr_tolower(const char* str); // returns new lowercase utf8 cstr -cstr cstr_tolower_ss(csubstr sv); // returns new lowercase utf8 cstr +cstr cstr_tolower_ss(csubstr ss); // returns new lowercase utf8 cstr void cstr_lowercase(cstr* self); // transform cstr to lowercase utf8 cstr cstr_toupper(const char* str); // returns new uppercase utf8 cstr -cstr cstr_toupper_ss(csubstr sv); // returns new uppercase utf8 cstr +cstr cstr_toupper_ss(csubstr ss); // returns new uppercase utf8 cstr void cstr_uppercase(cstr* self); // transform cstr to uppercase utf8 int cstr_icmp(const cstr* s1, const cstr* s2); // utf8 case-insensitive comparison diff --git a/docs/csubstr_api.md b/docs/csubstr_api.md index 925c69db..6cf76cf7 100644 --- a/docs/csubstr_api.md +++ b/docs/csubstr_api.md @@ -1,15 +1,16 @@ # STC [csubstr](../include/stc/csubstr.h): String View  -The type **csubstr** is a string view and can refer to a constant contiguous sequence of char-elements with the first -element of the sequence at position zero. The implementation holds two members: a pointer to constant char and a size. +The type **csubstr** is a non-null terminated string view and can refer to a constant contiguous sequence of +char-elements with the first element of the sequence at position zero. The implementation holds two members: +a pointer to constant char and a size. -**csubstr** is non-null terminated, and therefore not a replacent for `const char*` - see [csview](csview_api.md) for -that. **csubstr** never allocates memory, and therefore need not be destructed. -Its lifetime is limited by the source string storage. It keeps the length of the string, and does not need to call -*strlen()* to acquire the length. +Because **csubstr** is non-null terminated, it is not a replacent for `const char*` - see [csview](csview_api.md) +for that. **csubstr** never allocates memory, and therefore need not be destructed. Its lifetime is limited by +the source string storage. It keeps the length of the string, and does not need to call *strlen()* to acquire +the length. -Note: a **csubstr** may ***not be null-terminated***, and must therefore be printed this way: +Note: a **csubstr** must be printed the following way: ```c printf("%.*s", c_SS(sstr)) ``` @@ -29,47 +30,49 @@ All csubstr definitions and prototypes are available by including a single heade ## Methods ```c -csubstr c_ss(const char literal_only[]); // construct from literal, no strlen() -csubstr c_ss(const char* str, intptr_t n); // construct from str and length n +csubstr c_ss(const char literal_only[]); // construct from literal, no strlen() +csubstr c_ss(const char* str, intptr_t n); // construct from str and length n csubstr csubstr_from(const char* str); // construct from const char* csubstr csubstr_from_n(const char* str, intptr_t n); // alias for c_ss(str, n) -intptr_t csubstr_size(csubstr sv); -bool csubstr_empty(csubstr sv); +intptr_t csubstr_size(csubstr ss); +bool csubstr_empty(csubstr ss); void csubstr_clear(csubstr* self); -bool csubstr_equals(csubstr sv, csubstr sv2); -intptr_t csubstr_find(csubstr sv, const char* str); -intptr_t csubstr_find_ss(csubstr sv, csubstr find); -bool csubstr_contains(csubstr sv, const char* str); -bool csubstr_starts_with(csubstr sv, const char* str); -bool csubstr_ends_with(csubstr sv, const char* str); +bool csubstr_equals(csubstr ss, const char* str); +intptr_t csubstr_equals_ss(csubstr ss, csubstr find); +intptr_t csubstr_find(csubstr ss, const char* str); +intptr_t csubstr_find_ss(csubstr ss, csubstr find); +bool csubstr_contains(csubstr ss, const char* str); +bool csubstr_starts_with(csubstr ss, const char* str); +bool csubstr_ends_with(csubstr ss, const char* str); +csubstr csubstr_substr(csubstr ss, intptr_t pos, intptr_t n); +csubstr csubstr_slice(csubstr ss, intptr_t pos1, intptr_t pos2); -csubstr csubstr_substr_ex(csubstr sv, intptr_t pos, intptr_t n); // negative pos count from end -csubstr csubstr_slice_ex(csubstr sv, intptr_t p1, intptr_t p2); // negative p1, p2 count from end -csubstr csubstr_token(csubstr sv, const char* sep, intptr_t* start); // *start > sv.size after last token +csubstr csubstr_substr_ex(csubstr ss, intptr_t pos, intptr_t n); // negative pos count from end +csubstr csubstr_slice_ex(csubstr ss, intptr_t pos1, intptr_t pos2); // negative pos1, pos2 count from end +csubstr csubstr_token(csubstr ss, const char* sep, intptr_t* start); // *start > ss.size after last token ``` #### UTF8 methods ```c -intptr_t csubstr_u8_size(csubstr sv); -csubstr csubstr_u8_substr(csubstr sv, intptr_t bytepos, intptr_t u8len); -bool csubstr_valid_utf8(csubstr sv); // requires linking with src/utf8code.c - +intptr_t csubstr_u8_size(csubstr ss); +csubstr csubstr_u8_substr(csubstr ss, intptr_t bytepos, intptr_t u8len); +bool csubstr_valid_utf8(csubstr ss); // requires linking with src/utf8code.c + csubstr_iter csubstr_begin(const csubstr* self); csubstr_iter csubstr_end(const csubstr* self); -void csubstr_next(csubstr_iter* it); // utf8 codepoint step, not byte! +void csubstr_next(csubstr_iter* it); // utf8 codepoint step, not byte! csubstr_iter csubstr_advance(csubstr_iter it, intptr_t n); ``` -#### Extended cstr methods +#### cstr methods returning csubstr ```c +csubstr cstr_slice(const cstr* self, intptr_t pos1, intptr_t pos2); +csubstr cstr_slice_ex(const cstr* self, intptr_t pos1, intptr_t pos2); // see csubstr_slice_ex() csubstr cstr_substr(const cstr* self, intptr_t pos, intptr_t n); -csubstr cstr_substr_ex(const cstr* s, intptr_t pos, intptr_t n); // negative pos count from end +csubstr cstr_substr_ex(const cstr* self, intptr_t pos, intptr_t n); // see csubstr_substr_ex() csubstr cstr_u8_substr(const cstr* self, intptr_t bytepos, intptr_t u8len); - -csubstr cstr_slice(const cstr* self, intptr_t p1, intptr_t p2); -csubstr cstr_slice_ex(const cstr* s, intptr_t p, intptr_t q); // negative p or q count from end ``` #### Iterate tokens with *c_fortoken*, *c_fortoken_ss* @@ -99,7 +102,7 @@ uint64_t csubstr_hash(const csubstr* x); | Name | Value | Usage | |:---------------|:---------------------|:---------------------------------------------| -| `c_SS(sv)` | printf argument | `printf("sv: %.*s\n", c_SS(sv));` | +| `c_SS(ss)` | printf argument | `printf("ss: %.*s\n", c_SS(ss));` | ## Example ```c @@ -109,18 +112,18 @@ uint64_t csubstr_hash(const csubstr* x); int main(void) { - cstr str1 = cstr_lit("We think in generalities, but we live in details."); - // (quoting Alfred N. Whitehead) + cstr str1 = cstr_from("We think in generalities, but we live in details."); + // (quoting Alfred N. Whitehead) - csubstr sv1 = cstr_substr_ex(&str1, 3, 5); // "think" - intptr_t pos = cstr_find(&str1, "live"); // position of "live" in str1 - csubstr sv2 = cstr_substr_ex(&str1, pos, 4); // get "live" - csubstr sv3 = cstr_slice_ex(&str1, -8, -1); // get "details" + csubstr ss1 = cstr_substr_ex(&str1, 3, 5); // "think" + intptr_t pos = cstr_find(&str1, "live"); // position of "live" in str1 + csubstr ss2 = cstr_substr_ex(&str1, pos, 4); // get "live" + csubstr ss3 = cstr_slice_ex(&str1, -8, -1); // get "details" printf("%.*s %.*s %.*s\n", - c_SS(sv1), c_SS(sv2), c_SS(sv3)); + c_SS(ss1), c_SS(ss2), c_SS(ss3)); cstr s1 = cstr_lit("Apples are red"); - cstr s2 = cstr_from_ss(cstr_substr_ex(&s1, -3, 3)); // "red" - cstr s3 = cstr_from_ss(cstr_substr_ex(&s1, 0, 6)); // "Apples" + cstr s2 = cstr_from_ss(cstr_substr_ex(&s1, -3, 3)); // "red" + cstr s3 = cstr_from_ss(cstr_substr_ex(&s1, 0, 6)); // "Apples" printf("%s %s\n", cstr_str(&s2), cstr_str(&s3)); c_drop(cstr, &str1, &s1, &s2, &s3); diff --git a/docs/csview_api.md b/docs/csview_api.md index 4fdff0d1..f7e0e2b0 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -23,17 +23,15 @@ All csview definitions and prototypes are available by including a single header ```c csview c_sv(const char literal_only[]); // construct from literal, no strlen() -csview c_sv(const char* str, intptr_t n); // construct from str and length n csview csview_from(const char* str); // construct from const char* -csview csview_from_n(const char* str, intptr_t n); // alias for c_sv(str, n) intptr_t csview_size(csview sv); -bool csview_empty(csview sv); +bool csview_empty(csview sv); // check if size == 0 void csview_clear(csview* self); +csubstr csview_ss(csview sv); // convert to csubstr type -bool csview_equals(csview sv, csview sv2); +bool csview_equals(csview sv, const char* str); intptr_t csview_find(csview sv, const char* str); -intptr_t csview_find_sv(csview sv, csview find); bool csview_contains(csview sv, const char* str); bool csview_starts_with(csview sv, const char* str); bool csview_ends_with(csview sv, const char* str); diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 24967a10..1b4a2277 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -135,9 +135,9 @@ typedef const char* ccharptr; #define c_ss_2(str, n) (c_LITERAL(csubstr){str, n}) #define c_SS(ss) (int)(ss).size, (ss).str // printf("%.*s\n", c_SS(ss)); -#define c_sv(...) c_MACRO_OVERLOAD(c_sv, __VA_ARGS__) -#define c_sv_1(literal) c_sv_2(literal, c_litstrlen(literal)) +#define c_sv(literal) c_sv_2(literal, c_litstrlen(literal)) #define c_sv_2(str, n) (c_LITERAL(csview){str, n}) +#define c_SV(sv) c_SS(sv) // [deprecated] - unneeded #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 47cf65da..ce398628 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -115,7 +115,7 @@ STC_INLINE cstr cstr_from(const char* str) STC_INLINE cstr cstr_from_ss(csubstr sv) { return cstr_from_n(sv.str, sv.size); } -STC_INLINE cstr cstr_from_v(csview sv) +STC_INLINE cstr cstr_from_sv(csview sv) { return cstr_from_n(sv.str, sv.size); } STC_INLINE cstr cstr_with_size(const intptr_t size, const char value) { @@ -252,9 +252,6 @@ STC_INLINE bool cstr_equals(const cstr* self, const char* str) STC_INLINE bool cstr_equals_ss(const cstr* self, csubstr sv) { return sv.size == cstr_size(self) && !c_memcmp(cstr_str(self), sv.str, sv.size); } -STC_INLINE bool cstr_equals_sv(const cstr* self, csview sv) - { return sv.size == cstr_size(self) && !c_memcmp(cstr_str(self), sv.str, sv.size); } - STC_INLINE bool cstr_equals_s(const cstr* self, cstr s) { return !cstr_cmp(self, &s); } diff --git a/include/stc/csubstr.h b/include/stc/csubstr.h index 152f7041..c7a43052 100644 --- a/include/stc/csubstr.h +++ b/include/stc/csubstr.h @@ -45,8 +45,11 @@ STC_INLINE void csubstr_clear(csubstr* self) { *self = csubstr_init(); } STC_INLINE intptr_t csubstr_size(csubstr ss) { return ss.size; } STC_INLINE bool csubstr_empty(csubstr ss) { return ss.size == 0; } +STC_INLINE bool csubstr_equals_ss(csubstr ss1, csubstr ss2) + { return ss1.size == ss2.size && !c_memcmp(ss1.str, ss2.str, ss1.size); } + STC_INLINE bool csubstr_equals(csubstr ss, const char* str) - { intptr_t n = c_strlen(str); return ss.size == n && !c_memcmp(ss.str, str, n); } + { return csubstr_equals_ss(ss, c_ss_2(str, c_strlen(str))); } STC_INLINE intptr_t csubstr_find(csubstr ss, const char* str) { return csubstr_find_ss(ss, c_ss_2(str, c_strlen(str))); } diff --git a/include/stc/csview.h b/include/stc/csview.h index 0d1ca36c..367258e4 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -26,13 +26,12 @@ #ifndef CSVIEW_H_INCLUDED #define CSVIEW_H_INCLUDED -#define csview_init() c_sv_1("") +#define csview_init() c_sv("") #define csview_drop(p) c_default_drop(p) #define csview_clone(sv) c_default_clone(sv) -#define csview_from_n(str, n) c_sv_2(str, n) STC_INLINE csview csview_from(const char* str) - { return csview_from_n(str, c_strlen(str)); } + { return c_sv_2(str, c_strlen(str)); } STC_INLINE void csview_clear(csview* self) { *self = csview_init(); } STC_INLINE csubstr csview_ss(csview sv) { return c_ss_2(sv.str, sv.size); } @@ -44,14 +43,11 @@ STC_INLINE bool csview_equals(csview sv, const char* str) { return sv.size == n && !c_memcmp(sv.str, str, n); } -STC_INLINE intptr_t csview_find_v(csview sv, csview search) { - char* res = cstrnstrn(sv.str, search.str, sv.size, search.size); +STC_INLINE intptr_t csview_find(csview sv, const char* search) { + char* res = cstrnstrn(sv.str, search, sv.size, c_strlen(search)); return res ? (res - sv.str) : c_NPOS; } -STC_INLINE intptr_t csview_find(csview sv, const char* str) - { return csview_find_v(sv, c_sv_2(str, c_strlen(str))); } - STC_INLINE bool csview_contains(csview sv, const char* str) { return csview_find(sv, str) != c_NPOS; } diff --git a/misc/examples/strings/sso_substr.c b/misc/examples/strings/sso_substr.c index 3c6b1046..2262e349 100644 --- a/misc/examples/strings/sso_substr.c +++ b/misc/examples/strings/sso_substr.c @@ -5,7 +5,7 @@ int main(void) { - cstr str = cstr_lit("We think in generalities, but we live in details."); + cstr str = cstr_from("We think in generalities, but we live in details."); csubstr sv1 = cstr_substr_ex(&str, 3, 5); // "think" intptr_t pos = cstr_find(&str, "live"); // position of "live" csubstr sv2 = cstr_substr_ex(&str, pos, 4); // "live" @@ -13,8 +13,8 @@ int main(void) printf("%.*s, %.*s, %.*s\n", c_SS(sv1), c_SS(sv2), c_SS(sv3)); cstr_assign(&str, "apples are green or red"); - cstr s2 = cstr_from_ss(cstr_substr_ex(&str, -3, 3)); // "red" - cstr s3 = cstr_from_ss(cstr_substr_ex(&str, 0, 6)); // "apples" + cstr s2 = cstr_from_ss(cstr_substr_ex(&str, -3, 3)); // "red" + cstr s3 = cstr_from_ss(cstr_substr_ex(&str, 0, 6)); // "apples" printf("%s %s: %d, %d\n", cstr_str(&s2), cstr_str(&s3), cstr_is_long(&str), cstr_is_long(&s2)); c_drop (cstr, &str, &s2, &s3); |
