diff options
| author | Tyge Løvset <[email protected]> | 2022-11-06 15:52:16 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2022-11-06 15:52:16 +0100 |
| commit | 5ec606e5dfdbaebe22717d094b58ee7f365ffd9c (patch) | |
| tree | 80bcfce7b82dd836724d793f3de3c224ac376154 | |
| parent | bdbdf76616281f305ffc0af7f347f3fd8eaf0016 (diff) | |
| download | STC-modified-5ec606e5dfdbaebe22717d094b58ee7f365ffd9c.tar.gz STC-modified-5ec606e5dfdbaebe22717d094b58ee7f365ffd9c.zip | |
Added c_autodrop() macro, and removed c_autobuf() which wasn't that useful (and was undocumented).
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | docs/carray_api.md | 3 | ||||
| -rw-r--r-- | docs/ccommon_api.md | 15 | ||||
| -rw-r--r-- | examples/bits.c | 6 | ||||
| -rw-r--r-- | examples/bits2.c | 5 | ||||
| -rw-r--r-- | examples/cpque.c | 9 | ||||
| -rw-r--r-- | examples/new_arr.c | 9 | ||||
| -rw-r--r-- | examples/prime.c | 2 | ||||
| -rw-r--r-- | examples/regex2.c | 2 | ||||
| -rw-r--r-- | examples/regex_replace.c | 2 | ||||
| -rw-r--r-- | include/stc/alt/cstr.h | 10 | ||||
| -rw-r--r-- | include/stc/carr2.h | 2 | ||||
| -rw-r--r-- | include/stc/cbits.h | 2 | ||||
| -rw-r--r-- | include/stc/ccommon.h | 7 | ||||
| -rw-r--r-- | src/checkauto.l | 4 |
15 files changed, 38 insertions, 42 deletions
@@ -371,7 +371,7 @@ and non-emplace methods: #include <stc/cvec.h> // vector of string (cstr) ... c_auto (cvec_str, vec) // declare and call cvec_str_init() and defer cvec_str_drop(&vec) -c_with (cstr s = cstr_new("a string literal"), cstr_drop(&s)) // c_with is a more general c_auto. +c_autodrop (cstr, s, cstr_new("a string literal")) // like c_auto without auto default init. { const char* hello = "Hello"; cvec_str_push_back(&vec, cstr_from(hello); // construct and add string from const char* diff --git a/docs/carray_api.md b/docs/carray_api.md index e12cbc4f..fb2c6a89 100644 --- a/docs/carray_api.md +++ b/docs/carray_api.md @@ -90,8 +90,7 @@ int main() // Ex1 int xd = 30, yd = 20, zd = 10; // define arr3[30][20][10], initialized with zeros. - c_with (carr3_f arr3 = carr3_f_with_size(xd, yd, zd, 0.0f), - carr3_f_drop(&arr3)) { + c_autodrop (carr3_f, arr3, carr3_f_with_size(xd, yd, zd, 0.0f)) { arr3.data[5][4][3] = 3.14f; float *arr1 = arr3.data[5][4]; diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 7721a38d..8a11042b 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -3,19 +3,20 @@ The following macros are recommended to use, and they safe/have no side-effects. ## Scope macros (RAII) -### c_auto, c_with, c_scope, c_defer +### c_auto, c_autodrop, 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...)` | 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_auto (Type, var1,...,var4)` | `c_with (Type var1=Type_init(), Type_drop(&var1))` ... | +| `c_autodrop (Type, var, init...)` | Like `c_with (Type var=init..., Type_drop(&var))` | +| `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 | +| `continue` | Exit a block above 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. @@ -49,6 +50,12 @@ c_auto (cstr, s1, s2) printf("%s %s\n", cstr_str(&s1), cstr_str(&s2)); } +c_autodrop (cstr, str, cstr_new("Hello")) +{ + cstr_append(&str, " world"); + printf("%s\n", cstr_str(&str)); +} + // `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)) diff --git a/examples/bits.c b/examples/bits.c index ca4de6af..43a57c51 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -13,9 +13,9 @@ int main() cbits_reset(&set, 9); cbits_resize(&set, 43, false); - c_autobuf (str, char, cbits_size(&set) + 1) - printf(" str: %s\n", cbits_to_str(&set, str, 0, -1)); - + { char str[128]; + printf(" str: %s\n", cbits_to_str(&set, str, 0, 128)); + } printf("%4" c_ZU ": ", cbits_size(&set)); c_forrange (i, cbits_size(&set)) printf("%d", cbits_test(&set, i)); diff --git a/examples/bits2.c b/examples/bits2.c index 95eb8b83..59e0b337 100644 --- a/examples/bits2.c +++ b/examples/bits2.c @@ -11,12 +11,11 @@ int main() printf("size %" c_ZU "\n", Bits_size(&s1)); char buf[256]; - Bits_to_str(&s1, buf, 0, -1); + Bits_to_str(&s1, buf, 0, 256); printf("buf: %s: count=%" c_ZU "\n", buf, Bits_count(&s1)); Bits_reset(&s1, 8); - c_autobuf (str, char, Bits_size(&s1) + 1) - printf(" s1: %s\n", Bits_to_str(&s1, str, 0, -1)); + printf(" s1: %s\n", Bits_to_str(&s1, buf, 0, 256)); Bits s2 = Bits_clone(s1); diff --git a/examples/cpque.c b/examples/cpque.c index 63d07c6b..dba4552f 100644 --- a/examples/cpque.c +++ b/examples/cpque.c @@ -9,6 +9,7 @@ #include <stdbool.h> #include <stc/forward.h> #include <stc/views.h> +#include <stc/cstr.h> // predeclare declare_cpque(ipque, int); @@ -18,7 +19,7 @@ struct { bool (*less)(const int*, const int*); } typedef IPQueue; -#define IPQueue_obj(less) ((IPQueue){ipque_init(), less}) +#define IPQueue_drop(q) ipque_drop(&(q)->Q) #define i_type ipque #define i_val int @@ -52,9 +53,9 @@ int main() const int data[] = {1,8,5,6,3,4,0,9,7,2}, n = c_arraylen(data); print("data", data, n); - c_with (IPQueue q1 = IPQueue_obj(int_less), ipque_drop(&q1.Q)) // Max priority queue - c_with (IPQueue minq1 = IPQueue_obj(int_greater), ipque_drop(&minq1.Q)) // Min priority queue - c_with (IPQueue q5 = IPQueue_obj(int_lambda), ipque_drop(&q5.Q)) // Using lambda to compare elements. + c_autodrop (IPQueue, q1, {ipque_init(), int_less}) // Max priority queue + c_autodrop (IPQueue, minq1, {ipque_init(), int_greater}) // Min priority queue + c_autodrop (IPQueue, q5, {ipque_init(), int_lambda}) // Using lambda to compare elements. { c_forrange (i, n) ipque_push(&q1.Q, data[i]); diff --git a/examples/new_arr.c b/examples/new_arr.c index 598e5323..51955b46 100644 --- a/examples/new_arr.c +++ b/examples/new_arr.c @@ -13,8 +13,7 @@ int main() { int w = 7, h = 5, d = 3; - c_with (carr2_int volume = carr2_int_new_uninit(w, h), - carr2_int_drop(&volume)) + c_autodrop (carr2_int, volume, carr2_int_new_uninit(w, h)) { int *dat = carr2_int_data(&volume); for (size_t i = 0; i < carr2_int_size(&volume); ++i) @@ -30,8 +29,7 @@ int main() puts("\n"); } - c_with (carr3_int volume = carr3_int_new_uninit(w, h, d), - carr3_int_drop(&volume)) + c_autodrop (carr3_int, volume, carr3_int_new_uninit(w, h, d)) { int *dat = carr3_int_data(&volume); for (size_t i = 0; i < carr3_int_size(&volume); ++i) @@ -48,8 +46,7 @@ int main() puts(""); } - c_with (carr2_str text2d = carr2_str_with_size(h, d, cstr_init()), - carr2_str_drop(&text2d)) + c_autodrop (carr2_str, text2d, carr2_str_with_size(h, d, cstr_init())) { cstr_assign(&text2d.data[2][1], "hello"); cstr_assign(&text2d.data[4][0], "world"); diff --git a/examples/prime.c b/examples/prime.c index 287fb69b..d2fc5efa 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -28,7 +28,7 @@ int main(void) printf("computing prime numbers up to %" c_ZU "\n", n); clock_t t1 = clock(); - c_with (cbits primes = sieveOfEratosthenes(n + 1), cbits_drop(&primes)) { + c_autodrop (cbits, primes, sieveOfEratosthenes(n + 1)) { puts("done"); size_t np = cbits_count(&primes); clock_t t2 = clock(); diff --git a/examples/regex2.c b/examples/regex2.c index 1f656265..6dffc8c4 100644 --- a/examples/regex2.c +++ b/examples/regex2.c @@ -14,7 +14,7 @@ int main() {"!((abc|123)+)!", "!123abcabc!"} }; - c_with (cregex re = cregex_init(), cregex_drop(&re)) + c_auto (cregex, re) c_forrange (i, c_arraylen(s)) { int res = cregex_compile(&re, s[i].pattern, cre_default); diff --git a/examples/regex_replace.c b/examples/regex_replace.c index e6054d9f..13bc9bf0 100644 --- a/examples/regex_replace.c +++ b/examples/regex_replace.c @@ -35,7 +35,7 @@ int main() printf("brack: %s\n", cstr_str(&str)); /* Shows how to compile RE separately */ - c_with (cregex re = cregex_from(pattern, cre_default), cregex_drop(&re)) { + c_autodrop (cregex, re, cregex_from(pattern, cre_default)) { if (cregex_captures(&re) == 0) continue; // break c_with /* European date format. */ diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h index 17548b5d..728ce77f 100644 --- a/include/stc/alt/cstr.h +++ b/include/stc/alt/cstr.h @@ -310,11 +310,11 @@ STC_DEF void cstr_replace_at_sv(cstr* self, const size_t pos, size_t len, csview repl) { const size_t sz = cstr_size(self); if (len > sz - pos) len = sz - pos; - c_autobuf (xstr, char, repl.size) { - memcpy(xstr, repl.str, repl.size); - _cstr_internal_move(self, pos + len, pos + repl.size); - memcpy(&self->str[pos], xstr, repl.size); - } + char buf[256], *xstr = repl.size > 256 ? c_malloc(repl.size) : buf; + memcpy(xstr, repl.str, repl.size); + _cstr_internal_move(self, pos + len, pos + repl.size); + memcpy(&self->str[pos], xstr, repl.size); + if (repl.size > 256) c_free(xstr); } STC_DEF cstr diff --git a/include/stc/carr2.h b/include/stc/carr2.h index 01e4752c..fa46fd44 100644 --- a/include/stc/carr2.h +++ b/include/stc/carr2.h @@ -35,7 +35,7 @@ int main() { int w = 7, h = 5; - c_with (carr2_int image = carr2_int_new_uninit(w, h), carr2_int_drop(&image)) + c_autodrop (carr2_int, image, carr2_int_new_uninit(w, h)) { int *dat = carr2_int_data(&image); for (int i = 0; i < carr2_int_size(&image); ++i) diff --git a/include/stc/cbits.h b/include/stc/cbits.h index 6415c529..0b5c4db8 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_with (cbits bset = cbits_with_size(23, true), cbits_drop(&bset)) + c_autodrop (cbits, bset, cbits_with_size(23, true)) { cbits_reset(&bset, 9); cbits_resize(&bset, 43, false); diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 8f1599b5..f9aff743 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -222,6 +222,7 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, #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_autodrop(C, a, ...) for (C a = __VA_ARGS__, **_c_i = NULL; !_c_i; ++_c_i, C##_drop(&a)) #define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__) #define c_auto2(C, a) \ @@ -236,12 +237,6 @@ STC_INLINE char* cstrnstrn(const char *str, const char *needle, 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) -#define c_autobuf_N(b, type, n, BYTES) \ - for (type _c_b[((BYTES) - 1) / sizeof(type) + 1], \ - *b = (n)*sizeof *b > (BYTES) ? c_alloc_n(type, n) : _c_b \ - ; b; b != _c_b ? c_free(b) : (void)0, b = NULL) - #define c_drop(C, ...) do { c_forlist (_i, C*, {__VA_ARGS__}) C##_drop(*_i.ref); } while(0) #define c_find_if(...) c_MACRO_OVERLOAD(c_find_if, __VA_ARGS__) diff --git a/src/checkauto.l b/src/checkauto.l index 34aa280f..541bbf3f 100644 --- a/src/checkauto.l +++ b/src/checkauto.l @@ -43,9 +43,7 @@ do { block_type |= LOOP; state = BRACESDONE; } c_with | c_scope | c_defer | -c_autovar | -c_autoscope | -c_autodefer | +c_autodrop | c_auto { block_type = AUTO; state = BRACES; } \( { if (state == BRACES) ++braces_lev; } \) { if (state == BRACES && --braces_lev == 0) { |
