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