source: example/range_parser.cfa @ d9bad51

Last change on this file since d9bad51 was 03cdad6, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Added range-parser example.
I plan to reuse it to parse cpu device data.

  • Property mode set to 100644
File size: 1.4 KB
Line 
1#include <stdio.h>
2#include <fstream.hfa>
3#include <coroutine.hfa>
4
5coroutine RangeParser {
6        const char * text;
7        int com;
8};
9
10void ?{}(RangeParser & this, const char * text) {
11        this.text = text;
12}
13
14static inline void push(RangeParser & this, int val) { this.com = val; suspend; }
15static inline int next(RangeParser & this) { return resume(this).com; }
16
17void main(RangeParser & this) {
18        for() {
19                int start = -1, stop = -1;
20                int start_len = -1, stop_len = -1;
21                int ret = sscanf(this.text, "%u%n-%u%n", &start, &start_len, &stop, &stop_len);
22                switch(ret) {
23                case 0:
24                        // Not a range, maybe a comma?
25                        if(this.text[0] == ',') {
26                                this.text ++;
27                                continue;
28                        }
29
30                        serr | "Error: unexpected character in next range: '" | this.text |"'";
31                        exit(2);
32                case 1:
33                        // Only one value, push it!
34                        push(this, start);
35                        this.text += start_len;
36                        break;
37                case 2:
38                        if(start > stop) {
39                                serr | "Error: next range out of order '" | this.text |"'";
40                                exit(2);
41                        }
42                        for(int i = start; i <= stop; i++) {
43                                push(this, i);
44                        }
45                        this.text += stop_len;
46                        break;
47                default:
48                        serr | "Error reading next block: '" | this.text |"', returned" | ret;
49                        exit(2);
50                }
51
52                if(this.text[0] == '\0') break;
53        }
54        this.com = -1;
55}
56
57int main(int argc, char * argv[]) {
58        if(argc != 2) {
59                serr | "Usage:" | argv[0] | "range";
60                return 1;
61        }
62
63        RangeParser rp = { argv[1] };
64
65        for() {
66                int i = next(rp);
67                if(i < 0) break;
68                sout | i | nonl;
69        }
70        sout | nl;
71}
Note: See TracBrowser for help on using the repository browser.