summaryrefslogtreecommitdiffhomepage
path: root/docs
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2022-01-05 15:14:32 +0100
committerTyge Løvset <[email protected]>2022-01-05 15:14:32 +0100
commitead3df255f79f60257ae9626e7d52838de3caa67 (patch)
tree96e67304ff45b541ddc8b5119b6b0c4d7eb6a84b /docs
parent7083c748e2c00d0236146d21f9b20cfe69f953e6 (diff)
downloadSTC-modified-ead3df255f79f60257ae9626e7d52838de3caa67.tar.gz
STC-modified-ead3df255f79f60257ae9626e7d52838de3caa67.zip
Added docs on checkauto util program. Renamed (mainly internal) c_rawstr type to crawstr.
Diffstat (limited to 'docs')
-rw-r--r--docs/ccommon_api.md51
-rw-r--r--docs/cmap_api.md10
-rw-r--r--docs/cstr_api.md6
3 files changed, 43 insertions, 24 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index 10404a32..9fc33dc1 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -6,11 +6,6 @@ The following handy macros are safe to use, i.e. have no side-effects.
General ***defer*** mechanics for resource acquisition. These macros allows to specify the release of the
resource where the resource acquisition takes place. Makes it easier to verify that resources are released.
-**NB**: These macros are one-time executed **for-loops**. Use ***only*** `c_breakauto` in order to break out
-of these `c_auto*`-blocks! ***Do not*** use `return` or `goto` (or `break`) inside them, as they will
-prevent the `end`-statement to be executed when leaving scope. This is not particular to the `c_auto*()`
-macros, as one must always make sure to unwind temporary allocated resources before a `return` in C.
-
| Usage | Description |
|:---------------------------------------|:-----------------------------------------------------|
| `c_auto (Type, var...)` | `c_autovar (Type var=Type_init(), Type_drop(&var))` |
@@ -78,6 +73,36 @@ int main()
printf("%s\n", i.ref->str);
}
```
+### The checkauto utility program (for RAII)
+The **checkauto** program will check the source code for any misuses of the `c_auto*` macros that
+will lead to resource leakages. The `c_auto*`- macros are implemented as one-time executed **for-loops**,
+so any `return` or `break` appearing within such a block will lead to resource leaks, as it will disable
+the cleanup/drop method to be called. However, a `break` may (originally) been intended to break an immediate
+loop/switch outside the `c_auto` scope, so it would not work as intended in any case. The **checkauto**
+tool will report any such misusages. In general, one should therefore first break out of any inner loops
+with `break`, then use `c_breakauto` to break out of the `c_auto` scope(s). After this `return` may be used.
+
+Note that this is not a particular issue with the `c_auto*`-macros, as one must always make sure to unwind
+temporary allocated resources before a `return` in C. However, by using `c_auto*`-macros,
+- it is much easier to automatically detect misplaced return/break between resource acquisition and destruction.
+- it prevent forgetting to call the destructor at the end.
+```c
+for (int i = 0; i<n; ++i) {
+ c_auto (List, list) {
+ List_push_back(&list, i);
+ if (cond1())
+ break; // checkauto Error
+ for (j = 0; j<m; ++j) {
+ if (cond2())
+ break; // OK (breaks for-loop only)
+ }
+ if (cond3())
+ return; // checkauto Error
+ }
+ if (cond4())
+ return; // OK (outside c_auto)
+}
+```
### c_foreach, c_forpair
@@ -170,13 +195,15 @@ c_drop(cstr, &a, &b);
### General predefined template parameter functions
```
-int c_default_cmp(const Type*, const Type*);
-Type c_default_from(Type val); // simple copy
-Type c_default_toraw(const Type* val); // dereference val
-void c_default_drop(Type* val); // does nothing
-
-int c_rawstr_cmp(const char* const* a, const char* const* b);
-bool c_rawstr_eq(const char* const* a, const char* const* b);
+int c_default_cmp(const Type*, const Type*);
+Type c_default_from(Type val); // simple copy
+Type c_default_toraw(const Type* val); // dereference val
+void c_default_drop(Type* val); // does nothing
+
+typedef const char* crawstr;
+int crawstr_cmp(const crawstr* x, const crawstr* y);
+bool crawstr_eq(const crawstr* x, const crawstr* y);
+uint64_t crawstr_hash(const crawstr* x, size_t dummy);
```
### c_malloc, c_calloc, c_realloc, c_free
diff --git a/docs/cmap_api.md b/docs/cmap_api.md
index c5311e27..13f21ef5 100644
--- a/docs/cmap_api.md
+++ b/docs/cmap_api.md
@@ -84,18 +84,16 @@ cmap_X_raw cmap_X_value_toraw(cmap_X_value* pval);
```
Helpers:
```c
-uint64_t c_strhash(const char *str); // utility function
+uint64_t c_strhash(const char *str); // utility function
// hash template parameter functions:
-uint64_t c_default_hash(const void *data, size_t len); // key is any integral type
-uint64_t c_hash32(const void* data, size_t is4); // key is one 32-bit int
-uint64_t c_hash64(const void* data, size_t is8); // key is one 64-bit int
-uint64_t c_rawstr_hash(const char* const* strp, size_t unused);
+uint64_t c_default_hash(const void *data, size_t len); // key is any integral type
+uint64_t c_hash32(const void* data, size_t is4); // key is one 32-bit int
+uint64_t c_hash64(const void* data, size_t is8); // key is one 64-bit int
// equalto template parameter functions:
bool c_default_eq(const i_keyraw* a, const i_keyraw* b); // *a == *b
bool c_memcmp_eq(const i_keyraw* a, const i_keyraw* b); // !memcmp(a, b, sizeof *a)
-bool c_rawstr_eq(const char* const* a, const char* const* b); // !strcmp(*a, *b)
```
## Types
diff --git a/docs/cstr_api.md b/docs/cstr_api.md
index 31f27baf..4183ef7b 100644
--- a/docs/cstr_api.md
+++ b/docs/cstr_api.md
@@ -89,12 +89,6 @@ int cstr_cmp(const cstr *s1, const cstr *s2);
bool cstr_eq(const cstr *s1, const cstr *s2);
bool cstr_hash(const cstr *s, ...);
-typedef const char* c_rawstr;
-int c_rawstr_cmp(const c_rawstr* x, const c_rawstr* y);
-bool c_rawstr_eq(const c_rawstr* x, const c_rawstr* y);
-uint64_t c_rawstr_hash(const c_rawstr* x, size_t dummy);
-
-uint64_t c_strhash(const char* str);
char* c_strnstrn(const char* str, const char* needle, size_t slen, size_t nlen);
int c_strncasecmp(const char* str1, const char* str2, size_t n);
```