From 188717d9c7ca04e7b0e63e48cea0c55e5db11f05 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Thu, 20 May 2021 23:35:57 +0200 Subject: Added csview tokenizer (split string). --- docs/csview_api.md | 33 ++++++++++++++++++++++++++++----- include/stc/csview.h | 17 +++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/docs/csview_api.md b/docs/csview_api.md index fed7f6f4..e605c2bf 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -84,11 +84,11 @@ uint64_t csview_hash_ref(const csview* x, size_t ignored); ## Constants and macros -| Name | Value | Usage | -|:-----------------|:------------------ -|:---------------------------------| -| `csview_null` | same as `c_lit("")` | `sview = csview_null;` | -| `c_lit(literal)` | csview constructor | `sview = c_lit("hello, world");` | -| `csview_ARG(sv)` | printf argument | `printf("%.*s", csview_ARG(sv));`| +| Name | Value | Usage | +|:-----------------|:--------------------|:----------------------------------| +| `csview_null` | same as `c_lit("")` | `sview = csview_null;` | +| `c_lit(literal)` | csview constructor | `sview = c_lit("hello, world");` | +| `csview_ARG(sv)` | printf argument | `printf("%.*s", csview_ARG(sv));` | ## Container adaptors ``` @@ -169,3 +169,26 @@ Last element world: 200 ``` +### Example 2: string view tokensizer +Splits strings into tokens. **No** memory allocations, *strlen()*, or string zero-termination dependency. +```c +#include + +void splitstring(csview str, csview sep) +{ + csview token = csview_first_token(str, sep); + for (;;) { + printf("token: \"%.*s\"\n", csview_ARG(token)); + if (csview_end(&token).ref == csview_end(&str).ref) break; + token = csview_next_token(str, sep, token); + } + puts("--"); +} + +int main() +{ + splitstring(c_lit("//This is//double slash//separated//string"), c_lit("//")); + splitstring(c_lit("This has no matching separator"), c_lit("xx")); + splitstring(c_lit("Split,this,string,now,ok,"), c_lit(",")); +} +``` diff --git a/include/stc/csview.h b/include/stc/csview.h index d4d3f65d..7111471b 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -56,6 +56,7 @@ STC_INLINE void csview_clear(csview* self) { *self = csview_null; } STC_INLINE const char* csview_front(const csview* self) { return self->str; } STC_INLINE const char* csview_back(const csview* self) { return self->str + self->size - 1; } +#define csview_hash(sv) c_default_hash((sv).str, (sv).size) STC_INLINE bool csview_equals(csview sv, csview sv2) { return sv.size == sv2.size && !memcmp(sv.str, sv2.str, sv.size); } STC_INLINE size_t csview_find(csview sv, csview needle) @@ -75,6 +76,22 @@ STC_INLINE csview_iter_t csview_end(const csview* self) { return c_make(csview_iter_t){self->str + self->size}; } STC_INLINE void csview_next(csview_iter_t* it) { ++it->ref; } + +STC_INLINE csview csview_first_token(csview sv, csview sep) { + const char* res = c_strnstrn(sv.str, sep.str, sv.size, sep.size); + return c_make(csview){sv.str, (res ? res - sv.str : sv.size)}; +} + +STC_INLINE csview csview_next_token(csview sv, csview sep, csview token) { + if (token.str - sv.str + token.size == sv.size) + return c_make(csview){sv.str + sv.size, 0}; + token.str += token.size + sep.size; + size_t n = sv.size - (token.str - sv.str); + const char* res = c_strnstrn(token.str, sep.str, n, sep.size); + token.size = res ? res - token.str : n; + return token; +} + /* cstr interaction with csview: */ STC_INLINE cstr cstr_from_v(csview sv) -- cgit v1.2.3