summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-05-25 10:53:57 +0200
committerTyge Løvset <[email protected]>2021-05-25 10:53:57 +0200
commiteb4450324de7211fbd8c80a2c566f3a1bfddd3c7 (patch)
tree12e66d1c6d927df5903afb4fc27931b3b862d335
parent41ef6709c8371b6240b24b8258c12ba61c52cdcb (diff)
downloadSTC-modified-eb4450324de7211fbd8c80a2c566f3a1bfddd3c7.tar.gz
STC-modified-eb4450324de7211fbd8c80a2c566f3a1bfddd3c7.zip
Small refactoring and improved docs.
-rw-r--r--docs/ccommon_api.md26
-rw-r--r--examples/splitstr.c7
-rw-r--r--include/stc/cdeq.h4
-rw-r--r--include/stc/csmap.h4
-rw-r--r--include/stc/csview.h4
-rw-r--r--include/stc/cvec.h4
6 files changed, 28 insertions, 21 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index f26d55b7..93f46bf4 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -4,11 +4,14 @@ The following handy macros are safe to use, i.e. have no side-effects.
### c_forvar, c_fordefer, c_forbuffer
General ***defer*** mechanics for resource acquisition. These macros allows to specify the release of the
-resource where the resource acquisition is made. This ensures that resources are released after usage.
+resource near the resource acquisition, and makes it easier to verify that resources will be released.
**Note**: These macros are one-time executed **for**-loops. ***Only*** use `continue` in order to break out
of a `c_forvar` / `c_fordefer`-block. ***Do not*** use `return`, `goto` or `break`, as it will prevent the
-`release`-statement to be executed at the end. The same applies for `c_forbuffer`.
+`release`-statement to be executed at the end. The same applies for `c_forbuffer`. This is not particular to
+the `c_for*()` macros, as one must always make sure to unwind temporary allocated resources before `return` in C.
+
+The **c_forbuffer** uses stack memory if buffer is <= to 256 bytes, othewise it uses the slower heap memory.
| Usage | Description |
|:---------------------------------|:--------------------------------------------------|
@@ -16,14 +19,15 @@ of a `c_forvar` / `c_fordefer`-block. ***Do not*** use `return`, `goto` or `brea
| `c_fordefer (release...)` | Defer execution of `release` to end of block |
| `c_forbuffer (buf, type, n)` | Declare, allocate and free memory buffer |
-The `acquire`argument must be of the form: `type var = GetResource`. Note that the `release` argument can be
-a list of statements enclosed in parathesises. `c_forvar` can handle multiple variables of same type by using
-the `c_arg` macro: `c_forvar (c_arg(cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world"), cstr_del(&s1), cstr_del(&s2))`.
-
-**c_forbuffer** uses stack memory if buffer is <= to 256 bytes, othewise it uses the slower heap memory.
-
+The `acquire`argument must be of the form: `type var = GetResource`. For multiple variables, use multiple
+`c_forvar` in sequence, or if variables are of same type, the `c_arg` macro can be used:
+```
+c_forvar (c_arg(cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world")), cstr_del(&s1), cstr_del(&s2))
+{
+}
+```
+**Example**: Load each line of a text file into a vector of strings:
```c
-// Example: Load each line of a text file into a vector of strings
#include <errno.h>
#include <stc/cstr.h>
#include <stc/cvec.h>
@@ -119,5 +123,5 @@ c_del(cstr, &a, &b);
Memory allocator for the entire library. Macros can be overloaded by the user.
### c_swap, c_arraylen
-- **c_swap(type, x, y)**: Simple macro for swapping internals of two objects.
-- **c_arraylen(array)**: Return number of elements in an array, e.g. `int array[] = {1, 2, 3, 4};`
+- **c_swap(type, x, y)**: Simple macro for swapping internals of two objects.
+- **c_arraylen(array)**: Return number of elements in an array, e.g. `int array[] = {1, 2, 3, 4};`
diff --git a/examples/splitstr.c b/examples/splitstr.c
index 67499d0f..ba49ddcf 100644
--- a/examples/splitstr.c
+++ b/examples/splitstr.c
@@ -33,7 +33,10 @@ int main()
print_split(c_lit("This has no matching separator"), c_lit("xx")); puts("");
puts("Output from string_split():");
- c_forvar (cvec_str v = string_split(c_lit("Split,this,,string,now,"), c_lit(",")), cvec_str_del(&v))
- c_foreach (i, cvec_str, v)
+ cstr string = cstr_lit("Split,this,,string,now,");
+ cvec_str vec = string_split(c_sv(string), c_lit(","));
+
+ c_fordefer (cvec_str_del(&vec), cstr_del(&string))
+ c_foreach (i, cvec_str, vec)
printf("\t\"%s\"\n", i.ref->str);
} \ No newline at end of file
diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h
index ee0d1c2c..846a9c7f 100644
--- a/include/stc/cdeq.h
+++ b/include/stc/cdeq.h
@@ -199,14 +199,14 @@ struct cdeq_rep { size_t size, cap; void* base[]; };
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-static struct cdeq_rep _cdeq_inits = {0, 0};
+static struct cdeq_rep _cdeq_sentinel = {0, 0};
#define _cdeq_nfront(self) ((self)->data - (self)->_base)
#define _c_implement_cdeq(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
\
STC_DEF CX \
CX##_init(void) { \
- CX##_value_t *b = (CX##_value_t *) _cdeq_inits.base; \
+ CX##_value_t *b = (CX##_value_t *) _cdeq_sentinel.base; \
return c_make(CX){b, b}; \
} \
\
diff --git a/include/stc/csmap.h b/include/stc/csmap.h
index 3535897c..336280bf 100644
--- a/include/stc/csmap.h
+++ b/include/stc/csmap.h
@@ -308,14 +308,14 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; };
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-static struct csmap_rep _csmap_inits = {0, 0, 0, 0};
+static struct csmap_rep _csmap_sentinel = {0, 0, 0, 0, 0};
#define _c_implement_aatree(CX, C, Key, Mapped, keyCompareRaw, \
mappedDel, mappedFromRaw, mappedToRaw, RawMapped, \
keyDel, keyFromRaw, keyToRaw, RawKey) \
STC_DEF CX \
CX##_init(void) { \
- CX tree = {(CX##_node_t *) _csmap_inits.nodes}; \
+ CX tree = {(CX##_node_t *) _csmap_sentinel.nodes}; \
return tree; \
} \
\
diff --git a/include/stc/csview.h b/include/stc/csview.h
index bbb2752f..990104f1 100644
--- a/include/stc/csview.h
+++ b/include/stc/csview.h
@@ -81,8 +81,8 @@ STC_INLINE csview csview_first_token(csview sv, csview sep) {
}
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};
+ if (&token.str[token.size] == &sv.str[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);
diff --git a/include/stc/cvec.h b/include/stc/cvec.h
index e4feaf8a..3e7e37f2 100644
--- a/include/stc/cvec.h
+++ b/include/stc/cvec.h
@@ -203,13 +203,13 @@ struct cvec_rep { size_t size, cap; void* data[]; };
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-static struct cvec_rep _cvec_inits = {0, 0};
+static struct cvec_rep _cvec_sentinel = {0, 0};
#define _c_implement_cvec(CX, Value, valueCompareRaw, valueDel, valueFromRaw, valueToRaw, RawValue) \
\
STC_DEF CX \
CX##_init(void) { \
- CX cx = {(CX##_value_t *) _cvec_inits.data}; \
+ CX cx = {(CX##_value_t *) _cvec_sentinel.data}; \
return cx; \
} \
\