summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-02-23 12:38:38 +0100
committerTyge Løvset <[email protected]>2023-02-23 12:38:38 +0100
commit01f09f3c2f34ae960b091f6d4063750bccd3e777 (patch)
tree4ead1e1a6c89e74997283c5899285929a3c030be /include
parent4ff4c8d352f76b658214029988eab7ce1d69efe8 (diff)
downloadSTC-modified-01f09f3c2f34ae960b091f6d4063750bccd3e777.tar.gz
STC-modified-01f09f3c2f34ae960b091f6d4063750bccd3e777.zip
Renamed cco.h to coroutine.h
Diffstat (limited to 'include')
-rw-r--r--include/stc/algo/coroutine.h (renamed from include/stc/algo/cco.h)46
1 files changed, 23 insertions, 23 deletions
diff --git a/include/stc/algo/cco.h b/include/stc/algo/coroutine.h
index c94382b1..cf7acc16 100644
--- a/include/stc/algo/cco.h
+++ b/include/stc/algo/coroutine.h
@@ -31,7 +31,6 @@
* To use these macros to define a coroutine, you need to write a
* function that looks something like this:
*
- * [Re-entrant version using an explicit context structure]
*
* int ascending(cco_handle* ctx) {
* cco_context(ctx,
@@ -44,12 +43,12 @@
*
* cco_finish:; // add this to support cco_stop!
* );
+ *
* return -1;
* }
*
- * In the re-entrant version, you need to declare your persistent
- * variables by the `cco_context' macro. This macro takes the
- * cco_handle as first parameter.
+ * You declare your persistent variables with the `cco_context'
+ * macro. This macro takes the cco_handle as first parameter.
*
* Note that the context variable is set back to zero when the
* coroutine terminates (by cco_stop, or by control reaching
@@ -63,42 +62,43 @@
* case statements instead. That's why you can't put a cco_yield()
* inside a switch-statement.
*
- * The re-entrant macros will malloc() the state structure on first
- * call, and free() it when end is reached. If you want to
- * abort in the middle, you can use, the caller should call the
- * coroutine with `cco_stop(&ctx)' as parameter instead of &ctx alone.
+ * The macros will malloc() the state structure on first call, and
+ * free() it when end is reached. If you want to abort in the middle,
+ * the caller must call the coroutine with `cco_stop(&ctx)' as
+ * parameter instead of &ctx.
+ *
*
* Ground rules:
* - never put `cco_yield' within an explicit `switch'.
* - never put two `cco_yield' statements on the same source line.
* - add `cco_finish:' label at the end of the coroutine, before
* any cleanup code. Required to support cco_stop(ctx) argument.
+ * - in order to stop before all items are consumed, call the
+ * coroutine with `cco_stop(&handle)' as argument at the end.
*
* The caller of a re-entrant coroutine must provide a context
* variable:
*
* void main(void) {
- * cco_handle z = 0;
+ * cco_handle hnd = 0;
* for (;;) {
- * int x = ascending(&z);
- * if (!z) break;
+ * int x = ascending(&hnd);
+ * if (x == 5) cco_stop(&hnd);
+ * if (!hnd) break;
* printf("got number %d\n", x);
*
- * // stop if x == 5:
- * if (x == 5) ascending(cco_stop(&z));
* }
* }
*/
-
-#ifndef COROUTINE_H
-#define COROUTINE_H
+#ifndef STC_COROUTINE_INCLUDED
+#define STC_COROUTINE_INCLUDED
#include <stdlib.h>
#include <assert.h>
/*
* `c_' macros for re-entrant coroutines.
*/
-typedef struct {
+typedef struct ccoHandle {
int cco_line;
} *cco_handle;
@@ -116,19 +116,19 @@ typedef struct {
struct ccoContext *ctx = *_ccoparam; \
switch (ctx->cco_line) { \
case 0: __VA_ARGS__ break; \
- default: assert(!"cco_finish: missing"); \
+ default: assert(!"missing cco_finish:"); \
} \
free(ctx), *_ccoparam = NULL
-#define cco_yield(ret) \
+#define cco_yield(value) \
do { \
- (*_ccoparam)->cco_line = __LINE__; return ret; \
+ (*_ccoparam)->cco_line = __LINE__; return value; \
case __LINE__:; \
} while (0)
#define cco_finish case -1
-#define cco_stop(ctx) \
- ((*(ctx))->cco_line = -1, (ctx))
+static inline cco_handle* cco_stop(cco_handle* handle)
+ { (*handle)->cco_line = -1; return handle; }
-#endif /* COROUTINE_H */
+#endif // STC_COROUTINE_INCLUDED