diff options
| author | Tyge Løvset <[email protected]> | 2022-09-21 14:54:47 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-09-21 14:54:47 +0200 |
| commit | 307c0a111c8f063032ba90b2a7ae07122e2a2b1a (patch) | |
| tree | 0c989b52d7fe4a87d11dc593df5b16579dd1bd22 | |
| parent | a1d6c85b72027c9cd09d6bf0b1e0f7c3942e4aee (diff) | |
| download | STC-modified-307c0a111c8f063032ba90b2a7ae07122e2a2b1a.tar.gz STC-modified-307c0a111c8f063032ba90b2a7ae07122e2a2b1a.zip | |
Recent macro renames:
c_foreach_token() => c_fortoken()
c_foreach_match() => c_formatch()
Added:
c_forfiltered()
c_forpred()
| -rw-r--r-- | docs/cregex_api.md | 6 | ||||
| -rw-r--r-- | docs/csview_api.md | 8 | ||||
| -rw-r--r-- | examples/forfiltered.c | 93 | ||||
| -rw-r--r-- | examples/regex2.c | 2 | ||||
| -rw-r--r-- | examples/regex_match.c | 2 | ||||
| -rw-r--r-- | examples/splitstr.c | 8 | ||||
| -rw-r--r-- | include/stc/ccommon.h | 8 | ||||
| -rw-r--r-- | include/stc/cregex.h | 2 | ||||
| -rw-r--r-- | include/stc/csview.h | 15 |
9 files changed, 120 insertions, 24 deletions
diff --git a/docs/cregex_api.md b/docs/cregex_api.md index 6fd5ba1d..5f7e9136 100644 --- a/docs/cregex_api.md +++ b/docs/cregex_api.md @@ -122,9 +122,9 @@ if (cregex_find_pattern(pattern, input, match, 0)) To compile, use: `gcc first_match.c src/cregex.c src/utf8code.c`. In order to use a callback function in the replace call, see `examples/regex_replace.c`. -### Iterate through matches, c_foreach_match +### Iterate through regex matches, *c_formatch* -To iterate multiple matches in an input string, you may use: +To iterate multiple matches in an input string, you may use ```c csview match[5] = {0}; while (cregex_find(&re, input, match, cre_m_next) == cre_success) @@ -133,7 +133,7 @@ while (cregex_find(&re, input, match, cre_m_next) == cre_success) ``` There is also a safe macro which simplifies this: ```c -c_foreach_match (it, &re, input) +c_formatch (it, &re, input) c_forrange (int, k, cregex_captures(&re)) printf("submatch %d: %.*s\n", k, c_ARGsv(it.match[k])); ``` diff --git a/docs/csview_api.md b/docs/csview_api.md index 6597d192..5cc05c02 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -79,11 +79,11 @@ csview cstr_u8_substr(const cstr* self, size_t bytepos, size_t u8len); csview cstr_slice(const cstr* self, size_t p1, size_t p2); csview cstr_slice_ex(const cstr* s, intptr_t p, intptr_t q); // negative p or q count from end ``` -#### Iterate tokens with *c_foreach_token*, *c_foreach_token_sv* +#### Iterate tokens with *c_fortoken*, *c_fortoken_sv* To iterate tokens in an input string separated by a string: ```c -c_foreach_token (i, "hello, one, two, three", ", ") +c_fortoken (i, "hello, one, two, three", ", ") printf("token: %.*s\n", c_ARGsv(i.token)); ``` @@ -174,7 +174,7 @@ and does not depend on null-terminated strings. *string_split()* function return void print_split(csview input, csview sep) { - c_foreach_token_sv (i, input, sep) + c_fortoken_sv (i, input, sep) printf("[%.*s]\n", c_ARGsv(i.token)); } @@ -186,7 +186,7 @@ cstack_str string_split(csview input, csview sep) { cstack_str out = cstack_str_init(); - c_foreach_token_sv (i, input, sep) + c_fortoken_sv (i, input, sep) cstack_str_push(&out, cstr_from_sv(i.token)); return out; diff --git a/examples/forfiltered.c b/examples/forfiltered.c new file mode 100644 index 00000000..d2a62c2a --- /dev/null +++ b/examples/forfiltered.c @@ -0,0 +1,93 @@ +#include <stdio.h> +#include <stc/csview.h> + +#define i_type IVec +#define i_val int +#include <stc/cstack.h> + +#define i_type SVec +#define i_val_bind csview +#include <stc/cstack.h> + +void demo1(void) +{ + c_auto (IVec, vec) { + c_forarray (int, v, {0, 1, 2, 3, 4, 5, 80, 6, 7, 80, 8, 9, 80, 10, 11, 12, 13}) + IVec_push(&vec, *v); + + c_forfiltered (i, IVec, vec, *i.ref != 80) + printf(" %d", *i.ref); + + puts(""); + c_forfiltered (i, IVec, vec, i.idx >= 3 // drop(3) + && i.idx != 5 + && *i.ref != 7, + i.count < 5) // take(5) + printf(" %d", *i.ref); + puts(""); + } +} + + +/* Rust: +fn main() { + let vector = (1..) // Infinite range of integers + .filter(|x| x % 2 != 0) // Collect odd numbers + .take(5) // Only take five numbers + .map(|x| x * x) // Square each number + .collect::<Vec<usize>>(); // Return as a new Vec<usize> + println!("{:?}", vector); // Print result +} +*/ + +void demo2(void) +{ + c_auto (IVec, vec) { + int n = 0; + for (size_t x=1;; ++x) + if (n == 5) break; + else if (x & 1) ++n, IVec_push(&vec, x*x); + + c_foreach (i, IVec, vec) printf(" %d", *i.ref); + puts(""); + } +} + +/* Rust: +fn main() { + let sentence = "This is a sentence in Rust."; + let words: Vec<&str> = sentence + .split_whitespace() + .collect(); + let words_containing_i: Vec<&str> = words + .into_iter() + .take(2) + .filter(|word| word.contains("i")) + .collect(); + println!("{:?}", words_containing_i); +} +*/ +void demo3(void) +{ + c_auto (SVec, words, words_containing_i) { + const char* sentence = "This is a sentence in Rust."; + c_fortoken(w, sentence, " ") + SVec_push(&words, *w.ref); + + c_forfiltered (w, SVec, words, csview_contains(*w.ref, c_sv("i")), + w.count < 2) // take(2) + SVec_push(&words_containing_i, *w.ref); + + c_foreach (w, SVec, words_containing_i) + printf(" %.*s", c_ARGsv(*w.ref)); + puts(""); + } +} + + +int main(void) +{ + demo1(); + demo2(); + demo3(); +} diff --git a/examples/regex2.c b/examples/regex2.c index f0869d24..28291915 100644 --- a/examples/regex2.c +++ b/examples/regex2.c @@ -24,7 +24,7 @@ int main() } printf("input: %s\n", s[i].input); - c_foreach_match (j, &re, s[i].input) { + c_formatch (j, &re, s[i].input) { c_forrange (k, cregex_captures(&re)) printf(" submatch %d: %.*s\n", (int)k, c_ARGsv(j.match[k])); puts(""); diff --git a/examples/regex_match.c b/examples/regex_match.c index 78af5c77..50fdba9a 100644 --- a/examples/regex_match.c +++ b/examples/regex_match.c @@ -22,7 +22,7 @@ int main() printf("%d: %s\n", res, pattern); // extract and convert all numbers in str to floats - c_foreach_match (i, &re, str) + c_formatch (i, &re, str) cstack_float_push(&vec, atof(i.match[0].str)); c_foreach (i, cstack_float, vec) diff --git a/examples/splitstr.c b/examples/splitstr.c index f2a1dad1..8e976892 100644 --- a/examples/splitstr.c +++ b/examples/splitstr.c @@ -6,16 +6,16 @@ int main() { - puts("Split with c_foreach_token (csview):"); + puts("Split with c_fortoken (csview):"); - c_foreach_token (i, "Hello World C99!", " ") + c_fortoken (i, "Hello World C99!", " ") printf("'%.*s'\n", c_ARGsv(i.token)); - puts("\nSplit with c_foreach_match (regex):"); + puts("\nSplit with c_formatch (regex):"); c_with (cregex re = cregex_from("[^ ]+", 0), cregex_drop(&re)) - c_foreach_match (i, &re, " Hello World C99! ") + c_formatch (i, &re, " Hello World C99! ") printf("'%.*s'\n", c_ARGsv(i.match[0])); } diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index db273296..01af3111 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -164,13 +164,13 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle, #define c_forpred(i, C, cnt, pred) \ for (struct {C##_iter it; const C##_value *ref; size_t idx, count;} \ - i = {.it=C##_begin(&cnt), .ref=i.it.ref, .idx=0, .count=1} \ + i = {.it=C##_begin(&cnt), .ref=i.it.ref, .idx=0, .count=0} \ ; i.ref && (pred); C##_next(&i.it), i.ref = i.it.ref, ++i.idx) -#define c_forfilter(...) c_MACRO_OVERLOAD(c_forfilter, __VA_ARGS__) -#define c_forfilter4(it, C, cnt, filter) \ +#define c_forfiltered(...) c_MACRO_OVERLOAD(c_forfiltered, __VA_ARGS__) +#define c_forfiltered4(it, C, cnt, filter) \ c_forpred(it, C, cnt, true) if (!(filter)) ; else -#define c_forfilter5(it, C, cnt, filter, pred) \ +#define c_forfiltered5(it, C, cnt, filter, pred) \ c_forpred(it, C, cnt, pred) if (!((filter) && ++it.count)) ; else #define c_forpair(key, val, C, cnt) /* structured binding */ \ diff --git a/include/stc/cregex.h b/include/stc/cregex.h index 2222dc45..6c817f1c 100644 --- a/include/stc/cregex.h +++ b/include/stc/cregex.h @@ -77,7 +77,7 @@ typedef struct { csview match[cre_MAXCAPTURES]; } cregex_iter; -#define c_foreach_match(it, Re, Input) \ +#define c_formatch(it, Re, Input) \ for (cregex_iter it = {Re, Input}; \ cregex_find(it.re, it.input, it.match, cre_m_next) == cre_success;) diff --git a/include/stc/csview.h b/include/stc/csview.h index 5d30174f..f2ac1c42 100644 --- a/include/stc/csview.h +++ b/include/stc/csview.h @@ -31,7 +31,10 @@ #define csview_new(literal) c_sv(literal) #define csview_npos (SIZE_MAX >> 1) -STC_INLINE csview csview_init() { return csview_null; } +#define csview_init() csview_null +#define csview_drop(p) (p) +#define csview_clone(sv) (sv) + STC_INLINE csview csview_from(const char* str) { return c_make(csview){str, strlen(str)}; } STC_INLINE void csview_clear(csview* self) { *self = csview_null; } @@ -103,13 +106,13 @@ 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); -#define c_foreach_token_sv(it, input, sep) \ - for (struct { csview _inp, _sep, token; size_t pos; } \ - it = {._inp=input, ._sep=sep, .token=it._inp, .pos=0} \ +#define c_fortoken_sv(it, input, sep) \ + for (struct { csview _inp, _sep, token, *ref; size_t pos; } \ + it = {._inp=input, ._sep=sep, .token=it._inp, .ref=&it.token, .pos=0} \ ; it.pos <= it._inp.size && (it.token = csview_token(it._inp, it._sep, &it.pos)).str ; ) -#define c_foreach_token(it, input, sep) \ - c_foreach_token_sv(it, csview_from(input), csview_from(sep)) +#define c_fortoken(it, input, sep) \ + c_fortoken_sv(it, csview_from(input), csview_from(sep)) /* csview interaction with cstr: */ #ifdef CSTR_H_INCLUDED |
