From 90624d6d398ff1d0f79df3dd656c4ad0c9c498a9 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 9 Aug 2022 17:34:13 +0200 Subject: Experiment with other type of iterator. Does not compile. --- examples/regex_replace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples/regex_replace.c') diff --git a/examples/regex_replace.c b/examples/regex_replace.c index 1b140676..ccc90dba 100644 --- a/examples/regex_replace.c +++ b/examples/regex_replace.c @@ -36,7 +36,7 @@ int main() /* Shows how to compile RE separately */ c_autovar (cregex re = cregex_from(pattern, 0), cregex_drop(&re)) { if (cregex_captures(&re) == 0) - continue; + c_breakauto; /* European date format. */ cstr_take(&str, cregex_replace(input, &re, "$3.$2.$1", 0)); printf("euros: %s\n", cstr_str(&str)); -- cgit v1.2.3 From 9bdcf2090da121f8d0954dad35db48c7aa47b17e Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 13 Aug 2022 19:02:50 +0200 Subject: Experimental: Renamed c_autovar => c_with, c_autoscope => c_scope, c_autodefer => c_defer. May or may not be reverted before V4.0 release. --- README.md | 2 +- benchmarks/misc/string_bench_STC.cpp | 2 +- benchmarks/misc/string_bench_STD.cpp | 2 +- docs/carray_api.md | 6 ++-- docs/ccommon_api.md | 59 +++++++++++++++++++----------------- docs/cmap_api.md | 4 +-- docs/csmap_api.md | 4 +-- docs/csview_api.md | 2 +- examples/arc_demo.c | 2 +- examples/astar.c | 4 +-- examples/bits.c | 4 +-- examples/box.c | 2 +- examples/cstr_match.c | 2 +- examples/demos.c | 8 ++--- examples/new_arr.c | 12 ++++---- examples/person_arc.c | 2 +- examples/prime.c | 2 +- examples/read.c | 6 ++-- examples/regex_replace.c | 2 +- examples/replace.c | 2 +- examples/splitstr.c | 2 +- include/stc/alt/csmap.h | 2 +- include/stc/carr2.h | 2 +- include/stc/carr3.h | 2 +- include/stc/cbits.h | 2 +- include/stc/ccommon.h | 22 ++++++++------ include/stc/cmap.h | 2 +- include/stc/csmap.h | 2 +- src/checkauto.l | 3 ++ 29 files changed, 90 insertions(+), 78 deletions(-) (limited to 'examples/regex_replace.c') diff --git a/README.md b/README.md index b2eb6094..afab8712 100644 --- a/README.md +++ b/README.md @@ -380,7 +380,7 @@ and non-emplace methods: #include // vector of string (cstr) ... c_auto (cvec_str, vec) // declare and call cvec_str_init() and defer cvec_str_drop(&vec) -c_autovar (cstr s = cstr_new("a string literal"), cstr_drop(&s)) // c_autovar is a more general c_auto. +c_with (cstr s = cstr_new("a string literal"), cstr_drop(&s)) // c_with is a more general c_auto. { const char* hello = "Hello"; cvec_str_push_back(&vec, cstr_from(hello); // construct and add string from const char* diff --git a/benchmarks/misc/string_bench_STC.cpp b/benchmarks/misc/string_bench_STC.cpp index 065b6dd7..ae8e4c38 100644 --- a/benchmarks/misc/string_bench_STC.cpp +++ b/benchmarks/misc/string_bench_STC.cpp @@ -38,7 +38,7 @@ cvec_str read_file(const char* name) { cvec_str data = cvec_str_init(); c_auto (cstr, line) - c_autovar (FILE* f = fopen(name, "r"), fclose(f)) + c_with (FILE* f = fopen(name, "r"), fclose(f)) while (cstr_getline(&line, f)) cvec_str_emplace_back(&data, cstr_str(&line)); return data; diff --git a/benchmarks/misc/string_bench_STD.cpp b/benchmarks/misc/string_bench_STD.cpp index 5f033ca1..8bb87937 100644 --- a/benchmarks/misc/string_bench_STD.cpp +++ b/benchmarks/misc/string_bench_STD.cpp @@ -17,7 +17,7 @@ std::vector read_file(const char* name) { std::vector data; c_auto (cstr, line) - c_autovar (FILE* f = fopen(name, "r"), fclose(f)) + c_with (FILE* f = fopen(name, "r"), fclose(f)) while (cstr_getline(&line, f)) data.emplace_back(cstr_str(&line)); return data; diff --git a/docs/carray_api.md b/docs/carray_api.md index 579bf119..cede295e 100644 --- a/docs/carray_api.md +++ b/docs/carray_api.md @@ -91,8 +91,8 @@ int main() // Ex1 int xd = 30, yd = 20, zd = 10; // define arr3[30][20][10], initialized with zeros. - c_autovar (carr3_f arr3 = carr3_f_with_size(xd, yd, zd, 0.0f), - carr3_f_drop(&arr3)) { + c_with (carr3_f arr3 = carr3_f_with_size(xd, yd, zd, 0.0f), + carr3_f_drop(&arr3)) { arr3.data[5][4][3] = 3.14f; float *arr1 = arr3.data[5][4]; @@ -105,7 +105,7 @@ int main() // Ex2 int w = 256, h = 128; - c_autovar (carr2_i image = carr2_i_new_uninit(w, h), carr2_i_drop(&image)) { + c_with (carr2_i image = carr2_i_new_uninit(w, h), carr2_i_drop(&image)) { int n = 0; c_foreach (i, carr2_i, image) { uint32_t t = n++ % 256; diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 6745317d..d37d4d04 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -2,38 +2,41 @@ The following macros are recommended to use, and they safe/have no side-effects. -### c_auto, c_autovar, c_autoscope, c_autodefer +### c_auto, c_with, c_scope, c_defer General ***defer*** mechanics for resource acquisition. These macros allows you to specify the freeing of the resources at the point where the acquisition takes place. The **checkauto** utility described below, ensures that the `c_auto*` macros are used correctly. -| Usage | Description | -|:---------------------------------------|:-----------------------------------------------------| -| `c_auto (Type, var...)` | `c_autovar (Type var=Type_init(), Type_drop(&var))` | -| `c_autovar (Type var=init, end...)` | Declare `var`. Defer `end...` to end of block | -| `c_autoscope (init, end...)` | Execute `init`. Defer `end...` to end of block | -| `c_autodefer (end...)` | Defer `end...` to end of block | -| `c_breakauto` or `continue` | Break out of a `c_auto*`-block/scope without memleak | - -For multiple variables, use either multiple **c_autovar** in sequence, or declare variable outside -scope and use **c_autoscope**. Also, **c_auto** support up to 4 variables. +| Usage | Description | +|:---------------------------------------|:----------------------------------------------------------| +| `c_auto (Type, var...)` | Same as `c_with (Type var=Type_init(), Type_drop(&var))` | +| `c_with (Type var=init, drop)` | Declare `var`. Defer `drop...` to end of scope | +| `c_with (Type var=init, pred, drop)` | Adds a predicate in order to exit early if init failed | +| `c_scope (init, drop...)` | Execute `init` and defer `drop...` to end of scope | +| `c_defer (drop...)` | Defer `drop...` to end of scope | +| `continue` | Exit a `c_auto/c_with/c_scope...` without memory leaks | + +For multiple variables, use either multiple **c_with** in sequence, or declare variable outside +scope and use **c_scope**. For convenience, **c_auto** support up to 4 variables. ```c -c_autovar (uint8_t* buf = malloc(BUF_SIZE), free(buf)) -c_autovar (FILE* f = fopen(fname, "rb"), fclose(f)) +// `c_with` is similar to python `with`: it declares and can drop a variable after going out of scope. +c_with (uint8_t* buf = malloc(BUF_SIZE), free(buf)) +c_with (FILE* fp = fopen(fname, "rb"), fclose(fp)) { int n = 0; - if (f && buf) { - n = fread(buf, 1, BUF_SIZE, f); + if (fp && buf) { + n = fread(buf, 1, BUF_SIZE, fp); doSomething(buf, n); } } -c_autovar (cstr s = cstr_new("Hello"), cstr_drop(&s)) +c_with (cstr str = cstr_new("Hello"), cstr_drop(&str)) { - cstr_append(&s, " world"); - printf("%s\n", cstr_str(&s)); + cstr_append(&str, " world"); + printf("%s\n", cstr_str(&str)); } +// `c_auto` automatically initialize and destruct up to 4 variables, like `c_with`. c_auto (cstr, s1, s2) { cstr_append(&s1, "Hello"); @@ -45,14 +48,16 @@ c_auto (cstr, s1, s2) printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); } -MyData data; -c_autoscope (mydata_init(&data), mydata_destroy(&data)) +// `c_scope` is like `c_with` but works with an already declared variable. +static pthread_mutex_t mut; +c_scope (pthread_mutex_lock(&mut), pthread_mutex_unlock(&mut)) { - printf("%s\n", cstr_str(&mydata.name)); + /* Do syncronized work. */ } +// `c_defer` executes the expressions when leaving scope. cstr s1 = cstr_new("Hello"), s2 = cstr_new("world"); -c_autodefer (cstr_drop(&s1), cstr_drop(&s2)) +c_defer (cstr_drop(&s1), cstr_drop(&s2)) { printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); } @@ -70,16 +75,16 @@ cvec_str readFile(const char* name) { cvec_str vec = cvec_str_init(); // returned - c_autovar (FILE* fp = fopen(name, "r"), fclose(fp)) - c_autovar (cstr line = cstr_null, cstr_drop(&line)) - while (cstr_getline(&line, fp)) - cvec_str_emplace_back(&vec, cstr_str(&line)); + c_with (FILE* fp = fopen(name, "r"), fclose(fp)) + c_with (cstr line = cstr_null, cstr_drop(&line)) + while (cstr_getline(&line, fp)) + cvec_str_emplace_back(&vec, cstr_str(&line)); return vec; } int main() { - c_autovar (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) + c_with (cvec_str x = readFile(__FILE__), cvec_str_drop(&x)) c_foreach (i, cvec_str, x) printf("%s\n", cstr_str(i.ref)); } diff --git a/docs/cmap_api.md b/docs/cmap_api.md index 91c36def..792d6c8c 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -211,7 +211,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { // Define map with defered destruct - c_autovar (cmap_vi vecs = cmap_vi_init(), cmap_vi_drop(&vecs)) + c_with (cmap_vi vecs = cmap_vi_init(), cmap_vi_drop(&vecs)) { cmap_vi_insert(&vecs, (Vec3i){100, 0, 0}, 1); cmap_vi_insert(&vecs, (Vec3i){ 0, 100, 0}, 2); @@ -244,7 +244,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { - c_auto (cmap_iv, vecs) // shorthand for c_autovar with _init(), _drop(). + c_auto (cmap_iv, vecs) // shorthand for c_with with _init(), _drop(). { cmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); cmap_iv_insert(&vecs, 2, (Vec3i){ 0, 100, 0}); diff --git a/docs/csmap_api.md b/docs/csmap_api.md index 3a1a5aa6..91abaae3 100644 --- a/docs/csmap_api.md +++ b/docs/csmap_api.md @@ -157,7 +157,7 @@ int main() { uint32_t col = 0xcc7744ff; csmap_id idnames = csmap_id_init(); - c_autodefer (csmap_id_drop(&idnames)) + c_defer (csmap_id_drop(&idnames)) { c_forarray (csmap_id_raw, v, { {100, "Red"}, {110, "Blue"} }) csmap_id_emplace(&idnames, v->first, v->second); @@ -238,7 +238,7 @@ typedef struct { int x, y, z; } Vec3i; int main() { // equivalent to: c_auto (csmap_iv, vecs) - c_autovar (csmap_iv vecs = csmap_iv_init(), csmap_iv_drop(&vecs)) + c_with (csmap_iv vecs = csmap_iv_init(), csmap_iv_drop(&vecs)) { csmap_iv_insert(&vecs, 1, (Vec3i){100, 0, 0}); csmap_iv_insert(&vecs, 2, (Vec3i){0, 100, 0}); diff --git a/docs/csview_api.md b/docs/csview_api.md index 79d108a3..d6bb4baf 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -199,7 +199,7 @@ int main() print_split(c_sv("This has no matching separator"), c_sv("xx")); puts(""); - c_autovar (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) + c_with (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/arc_demo.c b/examples/arc_demo.c index 85e3886f..688fe72f 100644 --- a/examples/arc_demo.c +++ b/examples/arc_demo.c @@ -47,7 +47,7 @@ int main() printf("\nset:"); c_foreach (i, csset_Arc, set) printf(" %d", *i.ref->get); - c_autovar (Arc p = Arc_clone(vec.data[0]), Arc_drop(&p)) { + c_with (Arc p = Arc_clone(vec.data[0]), Arc_drop(&p)) { printf("\n%d is now owned by %ld objects\n", *p.get, *p.use_count); } diff --git a/examples/astar.c b/examples/astar.c index cb498b11..4d9f2469 100644 --- a/examples/astar.c +++ b/examples/astar.c @@ -131,7 +131,7 @@ astar(cstr* maze, int width) int main(void) { - c_autovar (cstr maze = cstr_new( + c_with (cstr maze = cstr_new( "#########################################################################\n" "# # # # # # #\n" "# # ######### # ##### ######### ##### ##### ##### # ! #\n" @@ -157,7 +157,7 @@ main(void) "#########################################################################\n"), cstr_drop(&maze)) { int width = cstr_find(&maze, "\n") + 1; - c_autovar (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path)) + c_with (cdeq_point path = astar(&maze, width), cdeq_point_drop(&path)) { c_foreach (it, cdeq_point, path) cstr_data(&maze)[point_index(it.ref)] = 'x'; printf("%s", cstr_str(&maze)); diff --git a/examples/bits.c b/examples/bits.c index 8cce573e..c6e70517 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -3,7 +3,7 @@ int main() { - c_autovar (cbits set = cbits_with_size(23, true), cbits_drop(&set)) { + c_with (cbits set = cbits_with_size(23, true), cbits_drop(&set)) { printf("count %" PRIuMAX ", %" PRIuMAX "\n", cbits_count(&set), cbits_size(&set)); cbits s1 = cbits_from("1110100110111"); char buf[256]; @@ -36,7 +36,7 @@ int main() printf("%d", cbits_test(&set, i)); puts(""); - c_autovar (cbits s2 = cbits_clone(set), cbits_drop(&s2)) { + c_with (cbits s2 = cbits_clone(set), cbits_drop(&s2)) { cbits_flip_all(&s2); cbits_set(&s2, 16); cbits_set(&s2, 17); diff --git a/examples/box.c b/examples/box.c index c7e649bf..b12f1f71 100644 --- a/examples/box.c +++ b/examples/box.c @@ -59,7 +59,7 @@ int main() puts(""); // Look-up Audrey! Create a temporary Person for lookup. - c_autovar (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) { + c_with (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) { const PBox *v = Persons_get(&vec, a); // lookup if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); } diff --git a/examples/cstr_match.c b/examples/cstr_match.c index 317ff986..614af490 100644 --- a/examples/cstr_match.c +++ b/examples/cstr_match.c @@ -4,7 +4,7 @@ int main() { - c_autovar (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { + c_with (cstr ss = cstr_new("The quick brown fox jumps over the lazy dog.JPG"), cstr_drop(&ss)) { size_t pos = cstr_find_at(&ss, 0, "brown"); printf("%" PRIuMAX " [%s]\n", pos, pos == cstr_npos ? "" : cstr_str(&ss) + pos); printf("equals: %d\n", cstr_equals(&ss, "The quick brown fox jumps over the lazy dog.JPG")); diff --git a/examples/demos.c b/examples/demos.c index cd715d46..331ef04f 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -3,7 +3,7 @@ void stringdemo1() { printf("\nSTRINGDEMO1\n"); - c_autovar (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_drop(&cs)) + c_with (cstr cs = cstr_new("one-nine-three-seven-five"), cstr_drop(&cs)) { printf("%s.\n", cstr_str(&cs)); @@ -35,7 +35,7 @@ void stringdemo1() void vectordemo1() { printf("\nVECTORDEMO1\n"); - c_autovar (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums)) + c_with (cvec_ix bignums = cvec_ix_with_capacity(100), cvec_ix_drop(&bignums)) { cvec_ix_reserve(&bignums, 100); for (size_t i = 10; i <= 100; i += 10) @@ -192,8 +192,8 @@ void mapdemo3() void arraydemo1() { printf("\nARRAYDEMO1\n"); - c_autovar (carr3_f arr3 = carr3_f_with_size(30, 20, 10, 0.0f), - carr3_f_drop(&arr3)) + c_with (carr3_f arr3 = carr3_f_with_size(30, 20, 10, 0.0f), + carr3_f_drop(&arr3)) { arr3.data[5][4][3] = 10.2f; float **arr2 = arr3.data[5]; diff --git a/examples/new_arr.c b/examples/new_arr.c index 17a96062..598e5323 100644 --- a/examples/new_arr.c +++ b/examples/new_arr.c @@ -13,8 +13,8 @@ int main() { int w = 7, h = 5, d = 3; - c_autovar (carr2_int volume = carr2_int_new_uninit(w, h), - carr2_int_drop(&volume)) + c_with (carr2_int volume = carr2_int_new_uninit(w, h), + carr2_int_drop(&volume)) { int *dat = carr2_int_data(&volume); for (size_t i = 0; i < carr2_int_size(&volume); ++i) @@ -30,8 +30,8 @@ int main() puts("\n"); } - c_autovar (carr3_int volume = carr3_int_new_uninit(w, h, d), - carr3_int_drop(&volume)) + c_with (carr3_int volume = carr3_int_new_uninit(w, h, d), + carr3_int_drop(&volume)) { int *dat = carr3_int_data(&volume); for (size_t i = 0; i < carr3_int_size(&volume); ++i) @@ -48,8 +48,8 @@ int main() puts(""); } - c_autovar (carr2_str text2d = carr2_str_with_size(h, d, cstr_init()), - carr2_str_drop(&text2d)) + c_with (carr2_str text2d = carr2_str_with_size(h, d, cstr_init()), + carr2_str_drop(&text2d)) { cstr_assign(&text2d.data[2][1], "hello"); cstr_assign(&text2d.data[4][0], "world"); diff --git a/examples/person_arc.c b/examples/person_arc.c index 272a3f72..bddf7bd6 100644 --- a/examples/person_arc.c +++ b/examples/person_arc.c @@ -62,7 +62,7 @@ int main() puts(""); // Look-up Audrey! - c_autovar (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) { + c_with (Person a = Person_new("Audrey", "Home"), Person_drop(&a)) { const PSPtr *v = Persons_get(&vec, a); if (v) printf("found: %s %s\n", cstr_str(&v->get->name), cstr_str(&v->get->last)); } diff --git a/examples/prime.c b/examples/prime.c index 85a66ee5..7af66f33 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -27,7 +27,7 @@ int main(void) printf("computing prime numbers up to %" PRIuMAX "\n", n); clock_t t1 = clock(); - c_autovar (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { + c_with (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { puts("done"); size_t np = cbits_count(&primes); clock_t t2 = clock(); diff --git a/examples/read.c b/examples/read.c index 26fc46dd..5a9a30d5 100644 --- a/examples/read.c +++ b/examples/read.c @@ -6,8 +6,8 @@ cvec_str read_file(const char* name) { cvec_str vec = cvec_str_init(); - c_autovar (FILE* f = fopen(name, "r"), fclose(f)) - c_autovar (cstr line = cstr_init(), cstr_drop(&line)) + c_with (FILE* f = fopen(name, "r"), fclose(f)) + c_with (cstr line = cstr_null, cstr_drop(&line)) while (cstr_getline(&line, f)) cvec_str_push(&vec, cstr_clone(line)); return vec; @@ -16,7 +16,7 @@ cvec_str read_file(const char* name) int main() { int n = 0; - c_autovar (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) + c_with (cvec_str vec = read_file(__FILE__), cvec_str_drop(&vec)) c_foreach (i, cvec_str, vec) printf("%5d: %s\n", ++n, cstr_str(i.ref)); diff --git a/examples/regex_replace.c b/examples/regex_replace.c index ccc90dba..2ccbfc3c 100644 --- a/examples/regex_replace.c +++ b/examples/regex_replace.c @@ -34,7 +34,7 @@ int main() printf("brack: %s\n", cstr_str(&str)); /* Shows how to compile RE separately */ - c_autovar (cregex re = cregex_from(pattern, 0), cregex_drop(&re)) { + c_with (cregex re = cregex_from(pattern, 0), cregex_drop(&re)) { if (cregex_captures(&re) == 0) c_breakauto; /* European date format. */ diff --git a/examples/replace.c b/examples/replace.c index 13b6eaaf..c22c71ff 100644 --- a/examples/replace.c +++ b/examples/replace.c @@ -11,7 +11,7 @@ int main () // Ustring positions: 0123456789*123456789*12345 cstr s = cstr_from(base); // "this is a test string." cstr m = cstr_clone(s); - c_autodefer (cstr_drop(&s), cstr_drop(&m)) { + c_defer (cstr_drop(&s), cstr_drop(&m)) { cstr_append(&m, cstr_str(&m)); cstr_append(&m, cstr_str(&m)); printf("%s\n", cstr_str(&m)); diff --git a/examples/splitstr.c b/examples/splitstr.c index 68c36291..c483fbe0 100644 --- a/examples/splitstr.c +++ b/examples/splitstr.c @@ -33,7 +33,7 @@ int main() print_split(c_sv("This has no matching separator"), c_sv("xx")); puts(""); - c_autovar (cstack_str s = string_split(c_sv("Split,this,,string,now,"), c_sv(",")), cstack_str_drop(&s)) + c_with (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/include/stc/alt/csmap.h b/include/stc/alt/csmap.h index 60a1b72a..4b90fb78 100644 --- a/include/stc/alt/csmap.h +++ b/include/stc/alt/csmap.h @@ -32,7 +32,7 @@ #include int main(void) { - c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) + c_with (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) { csmap_sx_emplace(&m, "Testing one", 1.234); csmap_sx_emplace(&m, "Testing two", 12.34); diff --git a/include/stc/carr2.h b/include/stc/carr2.h index f55cdd17..ffedb07d 100644 --- a/include/stc/carr2.h +++ b/include/stc/carr2.h @@ -35,7 +35,7 @@ int main() { int w = 7, h = 5; - c_autovar (carr2_int image = carr2_int_new_uninit(w, h), carr2_int_drop(&image)) + c_with (carr2_int image = carr2_int_new_uninit(w, h), carr2_int_drop(&image)) { int *dat = carr2_int_data(&image); for (int i = 0; i < carr2_int_size(&image); ++i) diff --git a/include/stc/carr3.h b/include/stc/carr3.h index fdc29b6f..07eac2a1 100644 --- a/include/stc/carr3.h +++ b/include/stc/carr3.h @@ -35,7 +35,7 @@ int main() { int w = 7, h = 5, d = 3; - c_autovar (carr3_int image = carr3_int_new_uninit(w, h, d), carr3_int_drop(&image)) + c_with (carr3_int image = carr3_int_new_uninit(w, h, d), carr3_int_drop(&image)) { int *dat = carr3_int_data(&image); for (int i = 0; i < carr3_int_size(&image); ++i) diff --git a/include/stc/cbits.h b/include/stc/cbits.h index 3f75226d..a1b84acd 100644 --- a/include/stc/cbits.h +++ b/include/stc/cbits.h @@ -27,7 +27,7 @@ Similar to boost::dynamic_bitset / std::bitset #include "cbits.h" int main() { - c_autovar (cbits bset = cbits_with_size(23, true), cbits_drop(&bset)) + c_with (cbits bset = cbits_with_size(23, true), cbits_drop(&bset)) { cbits_reset(&bset, 9); cbits_resize(&bset, 43, false); diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index a4ae28aa..58d74ddf 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -176,24 +176,28 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle, for (itype i=start, _inc=step, _end=(stop) - (0 < _inc) \ ; (i <= _end) == (0 < _inc); i += _inc) -#define c_autovar(...) c_MACRO_OVERLOAD(c_autovar, __VA_ARGS__) -#define c_autovar2(declvar, drop) for (declvar, **_c_i = NULL; !_c_i; ++_c_i, drop) -#define c_autovar3(declvar, pred, drop) for (declvar, **_c_i = NULL; !_c_i && (pred); ++_c_i, drop) -#define c_autoscope(init, drop) for (int _c_i = (init, 0); !_c_i; ++_c_i, drop) -#define c_autodefer(...) for (int _c_i = 0; !_c_i; ++_c_i, __VA_ARGS__) +#define c_autovar c_with // [deprecated] +#define c_autoscope c_scope // [deprecated] +#define c_autodefer c_defer // [deprecated] + +#define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__) +#define c_with2(declvar, drop) for (declvar, **_c_i = NULL; !_c_i; ++_c_i, drop) +#define c_with3(declvar, pred, drop) for (declvar, **_c_i = NULL; !_c_i && (pred); ++_c_i, drop) +#define c_scope(init, drop) for (int _c_i = (init, 0); !_c_i; ++_c_i, drop) +#define c_defer(...) for (int _c_i = 0; !_c_i; ++_c_i, __VA_ARGS__) #define c_breakauto continue #define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__) #define c_auto2(C, a) \ - c_autovar2(C a = C##_init(), C##_drop(&a)) + c_with2(C a = C##_init(), C##_drop(&a)) #define c_auto3(C, a, b) \ - c_autovar2(c_expand(C a = C##_init(), b = C##_init()), \ + c_with2(c_expand(C a = C##_init(), b = C##_init()), \ (C##_drop(&b), C##_drop(&a))) #define c_auto4(C, a, b, c) \ - c_autovar2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init()), \ + c_with2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init()), \ (C##_drop(&c), C##_drop(&b), C##_drop(&a))) #define c_auto5(C, a, b, c, d) \ - c_autovar2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ + c_with2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \ (C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a))) #define c_autobuf(b, type, n) c_autobuf_N(b, type, n, 256) diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 971d00a8..58774fb2 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -31,7 +31,7 @@ #include int main(void) { - c_autovar (cmap_ichar m = cmap_ichar_init(), cmap_ichar_drop(&m)) + c_with (cmap_ichar m = cmap_ichar_init(), cmap_ichar_drop(&m)) { cmap_ichar_emplace(&m, 5, 'a'); cmap_ichar_emplace(&m, 8, 'b'); diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 97f1fce1..c773e70f 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -32,7 +32,7 @@ #include int main(void) { - c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) + c_with (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m)) { csmap_sx_emplace(&m, "Testing one", 1.234); csmap_sx_emplace(&m, "Testing two", 12.34); diff --git a/src/checkauto.l b/src/checkauto.l index 5b4a9c68..384b3855 100644 --- a/src/checkauto.l +++ b/src/checkauto.l @@ -38,6 +38,9 @@ for | while | switch { block_type |= LOOP; state = BRACES; } do { block_type |= LOOP; state = BRACESDONE; } +c_with | +c_scope | +c_defer | c_autovar | c_autoscope | c_autodefer | -- cgit v1.2.3 From bf3c50da1a346b56b6846c0f7b9e7a222f602c2f Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 15 Aug 2022 16:54:56 +0200 Subject: More iterator fixes. Make sure cvec/cdeq find_in() return end() iterator if item not found. Small cstr API change to u8_replace*. --- docs/cdeq_api.md | 2 +- docs/cstr_api.md | 2 +- docs/csview_api.md | 2 +- docs/cvec_api.md | 4 ++-- examples/regex_replace.c | 2 +- examples/utf8replace_c.c | 2 +- include/stc/cdeq.h | 24 +++++++++++++----------- include/stc/cstr.h | 7 ++----- include/stc/cvec.h | 23 ++++++++++++----------- 9 files changed, 34 insertions(+), 34 deletions(-) (limited to 'examples/regex_replace.c') diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md index 79e6bf39..6a47313d 100644 --- a/docs/cdeq_api.md +++ b/docs/cdeq_api.md @@ -43,7 +43,7 @@ const cdeq_X_value* cdeq_X_at(const cdeq_X* self, size_t idx); const cdeq_X_value* cdeq_X_get(const cdeq_X* self, i_valraw raw); // return NULL if not found cdeq_X_value* cdeq_X_get_mut(cdeq_X* self, i_valraw raw); // mutable get cdeq_X_iter cdeq_X_find(const cdeq_X* self, i_valraw raw); -cdeq_X_iter cdeq_X_find_in(cdeq_X_iter i1, cdeq_X_iter i2, i_valraw raw); +cdeq_X_iter cdeq_X_find_in(cdeq_X_iter i1, cdeq_X_iter i2, i_valraw raw); // return cvec_X_end() if not found cdeq_X_value* cdeq_X_front(const cdeq_X* self); cdeq_X_value* cdeq_X_back(const cdeq_X* self); diff --git a/docs/cstr_api.md b/docs/cstr_api.md index f5414f1b..d4e292cd 100644 --- a/docs/cstr_api.md +++ b/docs/cstr_api.md @@ -99,7 +99,7 @@ size_t cstr_u8_size_n(const cstr self, size_t nbytes); // utf8 si size_t cstr_u8_to_pos(const cstr* self, size_t u8idx); // byte pos offset at utf8 codepoint index const char* cstr_u8_at(const cstr* self, size_t u8idx); // char* position at utf8 codepoint index csview cstr_u8_chr(const cstr* self, size_t u8idx); // get utf8 character as a csview -void cstr_u8_replace_at(cstr* self, size_t u8pos, size_t u8len, csview repl); // replace at utf8 indices +void cstr_u8_replace(cstr* self, size_t pos, size_t u8len, csview repl); // replace u8len utf8 chars // iterate utf8 codepoints cstr_iter cstr_begin(const cstr* self); diff --git a/docs/csview_api.md b/docs/csview_api.md index d6bb4baf..128a1c9d 100644 --- a/docs/csview_api.md +++ b/docs/csview_api.md @@ -146,7 +146,7 @@ int main() { c_auto (cstr, s1) { s1 = cstr_new("hell😀 w😀rld"); - cstr_u8_replace_at(&s1, 7, 1, c_sv("ø")); + cstr_u8_replace(&s1, cstr_find(&s1, "😀rld"), 1, c_sv("ø")); printf("%s\n", cstr_str(&s1)); c_foreach (i, cstr, s1) diff --git a/docs/cvec_api.md b/docs/cvec_api.md index a1d27a23..579f6eeb 100644 --- a/docs/cvec_api.md +++ b/docs/cvec_api.md @@ -49,9 +49,9 @@ size_t cvec_X_capacity(const cvec_X* self); const cvec_X_value* cvec_X_at(const cvec_X* self, size_t idx); const cvec_X_value* cvec_X_get(const cvec_X* self, i_valraw raw); // return NULL if not found cvec_X_value* cvec_X_at_mut(cvec_X* self, size_t idx); -cvec_X_value* cvec_X_get_mut(cvec_X* self, i_valraw raw); // get mutable value +cvec_X_value* cvec_X_get_mut(cvec_X* self, i_valraw raw); // find mutable value, return value ptr cvec_X_iter cvec_X_find(const cvec_X* self, i_valraw raw); -cvec_X_iter cvec_X_find_in(cvec_X_iter i1, cvec_X_iter i2, i_valraw raw); +cvec_X_iter cvec_X_find_in(cvec_X_iter i1, cvec_X_iter i2, i_valraw raw); // return cvec_X_end() if not found // On sorted vectors: cvec_X_iter cvec_X_binary_search(const cvec_X* self, i_valraw raw); // at elem == raw, else end cvec_X_iter cvec_X_lower_bound(const cvec_X* self, i_valraw raw); // at first elem >= raw, else end diff --git a/examples/regex_replace.c b/examples/regex_replace.c index 2ccbfc3c..8640ced1 100644 --- a/examples/regex_replace.c +++ b/examples/regex_replace.c @@ -36,7 +36,7 @@ int main() /* Shows how to compile RE separately */ c_with (cregex re = cregex_from(pattern, 0), cregex_drop(&re)) { if (cregex_captures(&re) == 0) - c_breakauto; + continue; // break c_with /* European date format. */ cstr_take(&str, cregex_replace(input, &re, "$3.$2.$1", 0)); printf("euros: %s\n", cstr_str(&str)); diff --git a/examples/utf8replace_c.c b/examples/utf8replace_c.c index 1bee9b44..e7659cfd 100644 --- a/examples/utf8replace_c.c +++ b/examples/utf8replace_c.c @@ -8,7 +8,7 @@ int main() { printf("%s\n", cstr_str(&hello)); /* replace second smiley at utf8 codepoint pos 7 */ - cstr_u8_replace_at(&hello, 7, 1, c_sv("🐨")); + cstr_u8_replace(&hello, cstr_find(&hello, "😀rld"), 1, c_sv("🐨")); printf("%s\n", cstr_str(&hello)); diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 128b85ee..0efbe064 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -29,7 +29,8 @@ struct cdeq_rep { size_t size, cap; unsigned base[1]; }; #define cdeq_rep_(self) c_unchecked_container_of((self)->_base, struct cdeq_rep, base) -#define it2_ref_(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref) +#define _it2_ptr(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref) +#define _it_ptr(it) (it.ref ? it.ref : it.end) #endif // CDEQ_H_INCLUDED #ifndef _i_prefix @@ -125,7 +126,7 @@ _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], con } STC_INLINE _cx_iter _cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) { - return _cx_memb(_insert_range)(self, (it.ref ? it.ref : it.end), &value, &value + 1); + return _cx_memb(_insert_range)(self, _it_ptr(it), &value, &value + 1); } STC_INLINE _cx_iter @@ -138,7 +139,7 @@ _cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { } STC_INLINE _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter i1, _cx_iter i2) { - return _cx_memb(_erase_range_p)(self, i1.ref, it2_ref_(i1, i2)); + return _cx_memb(_erase_range_p)(self, i1.ref, _it2_ptr(i1, i2)); } @@ -172,7 +173,7 @@ _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], cons } STC_INLINE _cx_iter _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { - return _cx_memb(_emplace_range)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); + return _cx_memb(_emplace_range)(self, _it_ptr(it), &raw, &raw + 1); } #endif // !_i_no_emplace @@ -194,7 +195,7 @@ _cx_memb(_get_mut)(_cx_self* self, _cx_raw raw) STC_INLINE void _cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, int(*cmp)(const _cx_value*, const _cx_value*)) { - qsort(i1.ref, it2_ref_(i1, i2) - i1.ref, sizeof *i1.ref, + qsort(i1.ref, _it2_ptr(i1, i2) - i1.ref, sizeof *i1.ref, (int(*)(const void*, const void*)) cmp); } @@ -407,8 +408,8 @@ STC_DEF _cx_iter _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) { _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) - for (_cx_iter j = it; p1 != p2; ++p1) - *j.ref++ = i_keyfrom((*p1)); + for (_cx_value* p = it.ref; p1 != p2; ++p1) + *p++ = i_keyfrom((*p1)); return it; } #endif // !_i_no_emplace @@ -418,8 +419,9 @@ STC_DEF _cx_iter _cx_memb(_copy_range)(_cx_self* self, _cx_value* pos, const _cx_value* p1, const _cx_value* p2) { _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); - if (it.ref) for (_cx_iter j; p1 != p2; ++p1) - *j.ref++ = i_keyclone((*p1)); + if (it.ref) + for (_cx_value* p = it.ref; p1 != p2; ++p1) + *p++ = i_keyclone((*p1)); return it; } #endif // !_i_no_clone @@ -428,13 +430,13 @@ _cx_memb(_copy_range)(_cx_self* self, _cx_value* pos, STC_DEF _cx_iter _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, _cx_raw raw) { - const _cx_value* p2 = it2_ref_(i1, i2); + const _cx_value* p2 = _it2_ptr(i1, i2); for (; i1.ref != p2; ++i1.ref) { const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) return i1; } - return i2; + i2.ref = NULL; return i2; // NB! } STC_DEF int diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 0728b110..99b60e49 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -370,11 +370,8 @@ STC_INLINE void cstr_replace_at(cstr* self, size_t pos, size_t len, const char* STC_INLINE void cstr_replace_at_s(cstr* self, size_t pos, size_t len, cstr repl) { cstr_replace_at_sv(self, pos, len, cstr_sv(&repl)); } -STC_INLINE void cstr_u8_replace_at(cstr* self, size_t u8pos, size_t u8len, csview repl) { - csview sv = cstr_sv(self); - const char* p = utf8_at(sv.str, u8pos); - cstr_replace_at_sv(self, p - sv.str, utf8_pos(p, u8len), repl); -} +STC_INLINE void cstr_u8_replace(cstr* self, size_t pos, size_t u8len, csview repl) + { cstr_replace_at_sv(self, pos, utf8_pos(cstr_str(self) + pos, u8len), repl); } STC_INLINE void cstr_insert(cstr* self, size_t pos, const char* str) diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 92065619..1be7211d 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -66,7 +66,8 @@ int main() { struct cvec_rep { size_t size, cap; unsigned data[1]; }; #define cvec_rep_(self) c_unchecked_container_of((self)->data, struct cvec_rep, data) -#define it2_ref_(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref) +#define _it2_ptr(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref) +#define _it_ptr(it) (it.ref ? it.ref : it.end) #endif // CVEC_H_INCLUDED #ifndef _i_prefix @@ -107,7 +108,7 @@ _cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], cons } STC_INLINE _cx_iter _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) { - return _cx_memb(_emplace_range)(self, (it.ref ? it.ref : it.end), &raw, &raw + 1); + return _cx_memb(_emplace_range)(self, _it_ptr(it), &raw, &raw + 1); } #endif // !_i_no_emplace @@ -169,7 +170,7 @@ _cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], con } STC_INLINE _cx_iter _cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) { - return _cx_memb(_insert_range)(self, (it.ref ? it.ref : it.end), &value, &value + 1); + return _cx_memb(_insert_range)(self, _it_ptr(it), &value, &value + 1); } STC_INLINE _cx_iter @@ -182,7 +183,7 @@ _cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { } STC_INLINE _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter i1, _cx_iter i2) { - return _cx_memb(_erase_range_p)(self, i1.ref, it2_ref_(i1, i2)); + return _cx_memb(_erase_range_p)(self, i1.ref, _it2_ptr(i1, i2)); } STC_INLINE const _cx_value* @@ -243,7 +244,7 @@ _cx_memb(_lower_bound)(const _cx_self* self, _cx_raw raw) { STC_INLINE void _cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, int(*cmp)(const _cx_value*, const _cx_value*)) { - qsort(i1.ref, it2_ref_(i1, i2) - i1.ref, sizeof(_cx_value), + qsort(i1.ref, _it2_ptr(i1, i2) - i1.ref, sizeof(_cx_value), (int(*)(const void*, const void*)) cmp); } @@ -396,8 +397,8 @@ _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) { _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1); if (it.ref) - for (_cx_iter j = it; p1 != p2; ++p1) - *j.ref++ = i_keyfrom((*p1)); + for (_cx_value* p = it.ref; p1 != p2; ++p1) + *p++ = i_keyfrom((*p1)); return it; } #endif // !_i_no_emplace @@ -405,19 +406,19 @@ _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos, #if !c_option(c_no_cmp) STC_DEF _cx_iter _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, _cx_raw raw) { - const _cx_value* p2 = it2_ref_(i1, i2); + const _cx_value* p2 = _it2_ptr(i1, i2); for (; i1.ref != p2; ++i1.ref) { const _cx_raw r = i_keyto(i1.ref); if (i_eq((&raw), (&r))) return i1; } - return i2; + i2.ref = NULL; return i2; // NB! } STC_DEF _cx_iter _cx_memb(_binary_search_in)(_cx_iter i1, _cx_iter i2, const _cx_raw raw, _cx_iter* lower_bound) { - const _cx_value* p2 = it2_ref_(i1, i2); + const _cx_value* p2 = _it2_ptr(i1, i2); _cx_iter mid = i1; while (i1.ref != p2) { mid.ref = i1.ref + (p2 - i1.ref)/2; @@ -429,7 +430,7 @@ _cx_memb(_binary_search_in)(_cx_iter i1, _cx_iter i2, const _cx_raw raw, else i1.ref = mid.ref + 1; } *lower_bound = i1.ref == i2.end ? i2 : i1; - return i2; + i2.ref = NULL; return i2; // NB! } STC_DEF int -- cgit v1.2.3