diff options
| author | Tyge Løvset <[email protected]> | 2022-07-31 09:15:36 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-07-31 10:32:12 +0200 |
| commit | 8a5478f7c14d4c7476d36b137fd7d2c8d95f2c13 (patch) | |
| tree | e54045852e198dfbecbd82a55a854698658c4a6b | |
| parent | 90b4371d8a36ab609c2200289634c171a19f7fff (diff) | |
| download | STC-modified-8a5478f7c14d4c7476d36b137fd7d2c8d95f2c13.tar.gz STC-modified-8a5478f7c14d4c7476d36b137fd7d2c8d95f2c13.zip | |
csview: csview_token(sv, sep, &start): now start > sv.size on last token. Removed usage of c_ARGsv() macro in examples => printf formatting ".*s". csview fully inlined.
| -rw-r--r-- | docs/csview_api.md | 64 | ||||
| -rw-r--r-- | examples/cstr_match.c | 4 | ||||
| -rw-r--r-- | examples/regex2.c | 2 | ||||
| -rw-r--r-- | examples/regex_match.c | 4 | ||||
| -rw-r--r-- | examples/splitstr.c | 32 | ||||
| -rw-r--r-- | examples/sso_substr.c | 3 | ||||
| -rw-r--r-- | examples/sview_split.c | 3 | ||||
| -rw-r--r-- | examples/utf8replace_c.c | 2 | ||||
| -rw-r--r-- | include/stc/csview.h | 75 | ||||
| -rw-r--r-- | include/stc/utf8.h | 2 |
10 files changed, 91 insertions, 100 deletions
diff --git a/docs/csview_api.md b/docs/csview_api.md index e6a89d5e..d0ca44e1 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -41,10 +41,9 @@ bool csview_contains(csview sv, csview search); bool csview_starts_with(csview sv, csview sub); bool csview_ends_with(csview sv, csview sub); -// requires i_implement defined before inclusion of csview.h csview csview_substr_ex(csview sv, intptr_t pos, size_t n); // negative pos count from end csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2); // negative p1, p2 count from end -csview csview_token(csview sv, csview sep, size_t* start); // see split example below. +csview csview_token(csview sv, csview sep, size_t* start); // *start > sv.size after last token ``` #### UTF8 methods @@ -55,11 +54,10 @@ csview csview_u8_slice(csview sv, size_t u8p1, size_t u8p2); csview_iter csview_begin(const csview* self); csview_iter csview_end(const csview* self); -void csview_next(csview_iter* it); // utf8 codepoint step, not byte! +void csview_next(csview_iter* it); // utf8 codepoint step, not byte! // requires linking with src/utf8code.c: bool csview_valid_utf8(csview sv); - // from utf8.h, linking src/utf8code.c: bool utf8_valid(const char* s); bool utf8_valid_n(const char* s, size_t nbytes); @@ -166,33 +164,32 @@ h,e,l,l,😀, ,w,ø,r,l,d, Splits strings into tokens. *print_split()* makes **no** memory allocations or *strlen()* calls, and does not depend on null-terminated strings. *string_split()* function returns a vector of cstr. ```c -#define i_implement // implement csview_token() function, define once. +#include <stdio.h> #include <stc/csview.h> -void print_split(csview str, csview sep) +void print_split(csview input, csview sep) { size_t pos = 0; - while (pos != str.size) { - csview tok = csview_token(str, sep, &pos); + while (pos <= input.size) { + csview tok = csview_token(input, sep, &pos); // print non-null-terminated csview - printf("[%" c_PRIsv "]\n", c_ARGsv(tok)); + printf("[%.*s]\n", c_ARGsv(tok)); } } #include <stc/cstr.h> - #define i_val_str -#include <stc/cvec.h> +#include <stc/cstack.h> -cvec_str string_split(csview str, csview sep) +cstack_str string_split(csview input, csview sep) { - cvec_str vec = cvec_str_init(); + cstack_str out = cstack_str_init(); size_t pos = 0; - while (pos != str.size) { - csview tok = csview_token(str, sep, &pos); - cvec_str_push_back(&vec, cstr_from_sv(tok)); + while (pos <= input.size) { + csview tok = csview_token(input, sep, &pos); + cstack_str_push(&out, cstr_from_sv(tok)); } - return vec; + return out; } int main() @@ -202,24 +199,25 @@ int main() print_split(c_sv("This has no matching separator"), c_sv("xx")); puts(""); - c_autovar (cvec_str v = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cvec_str_drop(&v)) - c_foreach (i, cvec_str, v) + c_autovar (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) + c_foreach (i, cstack_str, s) printf("[%s]\n", cstr_str(i.ref)); } ``` Output: ``` -"" -"This is a" -"double-slash" -"separated" -"string" - -"This has no matching separator" - -"Split" -"this" -"" -"string" -"now" -"" +[] +[This is a] +[double-slash] +[separated] +[string] + +[This has no matching separator] + +[Split] +[this] +[] +[string] +[now] +[] +``` diff --git a/examples/cstr_match.c b/examples/cstr_match.c index 9c4fa2d3..6927ed80 100644 --- a/examples/cstr_match.c +++ b/examples/cstr_match.c @@ -17,7 +17,7 @@ int main() csview ch1 = cstr_u8_chr(&s1, 7); csview ch2 = cstr_u8_chr(&s1, 10); printf("%s\nsize: %" PRIuMAX ", %" PRIuMAX "\n", cstr_str(&s1), cstr_u8_size(s1), cstr_size(s1)); - printf("ch1: %" c_PRIsv "\n", c_ARGsv(ch1)); - printf("ch2: %" c_PRIsv "\n", c_ARGsv(ch2)); + printf("ch1: %.*s\n", c_ARGsv(ch1)); + printf("ch2: %.*s\n", c_ARGsv(ch2)); } } diff --git a/examples/regex2.c b/examples/regex2.c index 307579d4..cc9464c3 100644 --- a/examples/regex2.c +++ b/examples/regex2.c @@ -24,7 +24,7 @@ int main() { c_forrange (j, cregex_captures(&re)) { - printf(" submatch %" PRIuMAX ": %" c_PRIsv "\n", j, c_ARGsv(m[j])); + printf(" submatch %" PRIuMAX ": %.*s\n", j, c_ARGsv(m[j])); } puts(""); } diff --git a/examples/regex_match.c b/examples/regex_match.c index cb0fdd11..72039fde 100644 --- a/examples/regex_match.c +++ b/examples/regex_match.c @@ -22,7 +22,7 @@ int main() } while (cregex_find(s, &re, m, cre_m_next) == 1) { - printf("%" c_PRIsv " ; ", c_ARGsv(m[0])); + printf("%.*s ; ", c_ARGsv(m[0])); } puts(""); @@ -30,7 +30,7 @@ int main() printf("groups: %d\n", res); if ((res = cregex_find("hello@wørld", &re, m, 0)) == 1) { c_forrange (i, res) - printf("match: [%" c_PRIsv "]\n", c_ARGsv(m[i])); + printf("match: [%.*s]\n", c_ARGsv(m[i])); } else printf("err: %d\n", res); } diff --git a/examples/splitstr.c b/examples/splitstr.c index 942d4eec..68c36291 100644 --- a/examples/splitstr.c +++ b/examples/splitstr.c @@ -1,27 +1,29 @@ -#include <stc/cstr.h> +#include <stdio.h> #include <stc/csview.h> -#define i_val_str -#include <stc/cvec.h> -void print_split(csview str, csview sep) +void print_split(csview input, csview sep) { size_t pos = 0; - while (pos != str.size) { - csview tok = csview_token(str, sep, &pos); + while (pos <= input.size) { + csview tok = csview_token(input, sep, &pos); // print non-null-terminated csview - printf("[%" c_PRIsv "]\n", c_ARGsv(tok)); + printf("[%.*s]\n", c_ARGsv(tok)); } } -cvec_str string_split(csview str, csview sep) +#include <stc/cstr.h> +#define i_val_str +#include <stc/cstack.h> + +cstack_str string_split(csview input, csview sep) { - cvec_str vec = cvec_str_init(); + cstack_str out = cstack_str_init(); size_t pos = 0; - while (pos != str.size) { - csview tok = csview_token(str, sep, &pos); - cvec_str_push_back(&vec, cstr_from_sv(tok)); + while (pos <= input.size) { + csview tok = csview_token(input, sep, &pos); + cstack_str_push(&out, cstr_from_sv(tok)); } - return vec; + return out; } int main() @@ -31,7 +33,7 @@ int main() print_split(c_sv("This has no matching separator"), c_sv("xx")); puts(""); - c_autovar (cvec_str v = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cvec_str_drop(&v)) - c_foreach (i, cvec_str, v) + c_autovar (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) + c_foreach (i, cstack_str, s) printf("[%s]\n", cstr_str(i.ref)); } diff --git a/examples/sso_substr.c b/examples/sso_substr.c index 4c49a942..b47512ea 100644 --- a/examples/sso_substr.c +++ b/examples/sso_substr.c @@ -9,8 +9,7 @@ int main () size_t pos = cstr_find(str, "live"); // position of "live" csview sv2 = cstr_substr_ex(&str, pos, 4); // "live" csview sv3 = cstr_slice_ex(&str, -8, -1); // "details" - printf("%" c_PRIsv ", %" c_PRIsv ", %" c_PRIsv "\n", - c_ARGsv(sv1), c_ARGsv(sv2), c_ARGsv(sv3)); + printf("%.*s, %.*s, %.*s\n", c_ARGsv(sv1), c_ARGsv(sv2), c_ARGsv(sv3)); cstr_assign(&str, "apples are green or red"); cstr s2 = cstr_from_sv(cstr_substr_ex(&str, -3, 3)); // "red" diff --git a/examples/sview_split.c b/examples/sview_split.c index 2c7ce395..155cdc28 100644 --- a/examples/sview_split.c +++ b/examples/sview_split.c @@ -11,8 +11,7 @@ int main() const csview month = csview_token(date, c_sv("/"), &pos); const csview day = csview_token(date, c_sv("/"), &pos); - printf("%" c_PRIsv ", %" c_PRIsv ", %" c_PRIsv "\n", - c_ARGsv(year), c_ARGsv(month), c_ARGsv(day)); + printf("%.*s, %.*s, %.*s\n", c_ARGsv(year), c_ARGsv(month), c_ARGsv(day)); c_auto (cstr, y, m, d) { y = cstr_from_sv(year), m = cstr_from_sv(month), d = cstr_from_sv(day); diff --git a/examples/utf8replace_c.c b/examples/utf8replace_c.c index 86d8bd69..792654b6 100644 --- a/examples/utf8replace_c.c +++ b/examples/utf8replace_c.c @@ -16,7 +16,7 @@ int main() { printf("%s\n", cstr_str(&hello)); c_foreach (c, cstr, hello) - printf("%" c_PRIsv ",", c_ARGsv(c.chr)); + printf("%.*s,", c_ARGsv(c.chr)); puts(""); } } diff --git a/include/stc/csview.h b/include/stc/csview.h index ec40a8be..b4b701f2 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -31,10 +31,6 @@ #define csview_new(literal) c_sv(literal) #define csview_npos (SIZE_MAX >> 1) -STC_API csview csview_substr_ex(csview sv, intptr_t pos, size_t n); -STC_API csview csview_slice_ex(csview sv, intptr_t p1, intptr_t p2); -STC_API csview csview_token(csview sv, csview sep, size_t* start); - STC_INLINE csview csview_init() { return csview_null; } STC_INLINE csview csview_from(const char* str) { return c_make(csview){str, strlen(str)}; } @@ -102,6 +98,40 @@ STC_INLINE csview csview_u8_slice(csview sv, size_t u8p1, size_t u8p2) STC_INLINE bool csview_valid_utf8(csview sv) // depends on src/utf8code.c { return utf8_valid_n(sv.str, sv.size); } +/* "Rarely" used extended substr_ex(), slice_ex(), and token() function */ + +STC_INLINE csview +csview_substr_ex(csview sv, intptr_t pos, size_t n) { + if (pos < 0) { + pos += sv.size; + if (pos < 0) pos = 0; + } + if (pos > (intptr_t)sv.size) pos = sv.size; + if (pos + n > sv.size) n = sv.size - pos; + sv.str += pos, sv.size = n; + return sv; +} + +STC_INLINE csview +csview_slice_ex(csview sv, intptr_t p1, intptr_t p2) { + if (p1 < 0) { + p1 += sv.size; + if (p1 < 0) p1 = 0; + } + if (p2 < 0) p2 += sv.size; + if (p2 > (intptr_t)sv.size) p2 = sv.size; + sv.str += p1, sv.size = p2 > p1 ? p2 - p1 : 0; + return sv; +} + +STC_INLINE csview +csview_token(csview sv, csview sep, size_t* start) { + csview slice = {sv.str + *start, sv.size - *start}; + const char* res = c_strnstrn(slice.str, sep.str, slice.size, sep.size); + csview tok = {slice.str, res ? res - slice.str : slice.size}; + *start += tok.size + sep.size; + return tok; +} /* csview interaction with cstr: */ #ifdef CSTR_H_INCLUDED @@ -139,43 +169,6 @@ STC_INLINE bool csview_eq(const csview* x, const csview* y) STC_INLINE uint64_t csview_hash(const csview *self) { return c_fasthash(self->str, self->size); } -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined(i_implement) || defined(i_extern) - -STC_DEF csview -csview_substr_ex(csview sv, intptr_t pos, size_t n) { - if (pos < 0) { - pos += sv.size; - if (pos < 0) pos = 0; - } - if (pos > (intptr_t)sv.size) pos = sv.size; - if (pos + n > sv.size) n = sv.size - pos; - sv.str += pos, sv.size = n; - return sv; -} - -STC_DEF csview -csview_slice_ex(csview sv, intptr_t p1, intptr_t p2) { - if (p1 < 0) { - p1 += sv.size; - if (p1 < 0) p1 = 0; - } - if (p2 < 0) p2 += sv.size; - if (p2 > (intptr_t)sv.size) p2 = sv.size; - sv.str += p1, sv.size = p2 > p1 ? p2 - p1 : 0; - return sv; -} - -STC_DEF csview -csview_token(csview sv, csview sep, size_t* start) { - csview slice = {sv.str + *start, sv.size - *start}; - const char* res = c_strnstrn(slice.str, sep.str, slice.size, sep.size); - csview tok = {slice.str, res ? res - slice.str : (sep.size = 0, slice.size)}; - *start += tok.size + sep.size; - return tok; -} - -#endif #endif #undef i_opt #undef i_header diff --git a/include/stc/utf8.h b/include/stc/utf8.h index 41d2f315..c6fb6944 100644 --- a/include/stc/utf8.h +++ b/include/stc/utf8.h @@ -14,7 +14,7 @@ int main() printf("%s\n", cstr_str(&s1)); c_foreach (i, cstr, s1) - printf("%" c_PRIsv ",", c_ARGsv(i.chr)); + printf("%.*s,", c_ARGsv(i.chr)); } } // Output: |
