source: example/range_parser.cfa@ d9b7b66

Last change on this file since d9b7b66 was 03cdad6, checked in by Thierry Delisle <tdelisle@…>, 4 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.