1 /* -*- Mode: c; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <stdnoreturn.h>
7 #include <concurrent/concurrent.h>
8 #include <concurrent/shortname.h>
9
10
11 struct strsplit {
12 struct concurrent_ctx *concurrent;
13 char *str;
14 char c;
15 };
16
17 struct split_position {
18 char *s;
19 size_t len;
20 };
21
22 static void strsplit_coroutine(struct concurrent_ctx *ctx);
23
24 static struct strsplit *
strsplit_new(char * str,char c)25 strsplit_new(char *str, char c)
26 {
27 struct strsplit *s;
28 const size_t stack_size = 1024*4;
29 s = malloc(sizeof(*s));
30 s->concurrent = malloc(ctx_sizeof());
31 ctx_construct(s->concurrent, malloc(stack_size), stack_size, strsplit_coroutine, s);
32 s->str = str;
33 s->c = c;
34 return s;
35 }
36
37 static void
strsplit_del(struct strsplit * s)38 strsplit_del(struct strsplit *s)
39 {
40 free(ctx_get_stack(s->concurrent));
41 free(s->concurrent);
42 free(s);
43 }
44
45 static void
strsplit_coroutine(struct concurrent_ctx * ctx)46 strsplit_coroutine(struct concurrent_ctx *ctx)
47 {
48 struct strsplit *s = ctx_get_user_ptr(ctx);
49 char *p = s->str, *q = s->str;
50 do {
51 q = strchr(p, s->c);
52 size_t len = q ? (size_t)(q - p) : strlen(p);
53 yield_value(ctx, &(struct split_position){p, len});
54 p = q + 1;
55 } while (q);
56 }
57
58 struct split_position *
strsplit_next(struct strsplit * s)59 strsplit_next(struct strsplit *s)
60 {
61 return resume(s->concurrent);
62 }
63
64
main(void)65 int main(void)
66 {
67 concurrent_init();
68
69 char *text = "monday|tuesday|wednesday|thursday|friday|saturday|sunday";
70 struct strsplit *s = strsplit_new(text, '|');
71 struct split_position *p;
72 while ((p = strsplit_next(s)) != NULL) {
73 printf("%.*s\n", (int)p->len, p->s);
74 }
75 strsplit_del(s);
76
77 concurrent_fin();
78 return EXIT_SUCCESS;
79 }
80
81 /* output
82
83 $ ./a.out
84 monday
85 tuesday
86 wednesday
87 thursday
88 friday
89 saturday
90 sunday
91 */
92